Egy fájl utolsó oszlopának törlése a Linux rendszerben

Törölni akarok egy txt fájl utolsó oszlopát, miközben nem tudom, hogy mi az oszlop száma van. Hogyan tehettem ezt?

Példa:

Bemenet:

1223 1234 1323 ... 2222 123 1233 1234 1233 ... 3444 125 0000 5553 3455 ... 2334 222 

És azt akarom, hogy a kimenetem legyen :

1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Megjegyzések

  • Ezt sokféleképpen lehet megtenni .. kérjük, adjon hozzá egy példát, és a várható kimenet belőle ..
  • @heemayl rendben én csináltam
  • köszi … az oszlopok fület különválasztják vagy a szóközt elválasztják?
  • @heemayl szóköz elválasztó
  • cut úgy hangzik, mint a munka eszköze.

Válasz

A következővel: awk:

awk "NF{NF-=1};1" <in >out 

vagy:

awk "NF{NF--};1" <in >out 

vagy:

awk "NF{--NF};1" <in >out 

Ez ugyan voodoo-nak tűnik, de működik. Ezen awk parancsok mindegyikének három része van.

Az első NF, amely a második rész előfeltétele. A NF egy sor mezőinek számát tartalmazó változó. Az AWK-ban a dolgok akkor igazak, ha “nem 0 vagy üres karakterlánc "". Ezért a második rész (ahol NF csökkentve van) csak akkor történik, ha a NF nem 0.

A második rész (vagy NF-=1 NF-- vagy --NF) éppen kivon egyet a NF változóból. Ez megakadályozza az utolsó mező nyomtatását, mert amikor megváltoztat egy mezőt (ebben az esetben eltávolítja az utolsó mezőt), awk újrakonstruál $0, alapértelmezés szerint összefűzi az összes mezőt szóközzel elválasztva . $0 már nem tartalmazta az utolsó mezőt.

Az utolsó rész 1. “Nem varázslatos, csak kifejezésként használja, ami true -t jelenti. Ha egy awk kifejezés minden társított művelet nélkül igazra értékel, akkor az awk alapértelmezett művelet print $0 .

Megjegyzések

  • @JJoao: Ah, köszönöm, elfelejtettem a -- t. Megjegyzés: jelenleg a ;1 fájlra van szükség a POSIX-kompatibilishez.
  • A kezdeti ösztönöm az lenne, ha a for ciklust használnám, de ez sokkal tömörebb és okosabb.
  • ' érdemes megjegyezni, hogy ha ' nem alapértelmezett elválasztót használ, akkor ' meg kell változtatnom. Feltételezve, hogy a , az Ön elválasztója: awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
  • Az NF csökkentésének hatása a POSIX által nem meghatározott viselkedés – megkapja különböző kimenet attól függően, hogy melyik awk-ot futtatja '. Néhány awk eltávolítja az utolsó mezőt, ahogy szeretné, egyesek semmit sem tesznek, mások pedig jelenthetnek szintaxis hibát, vagy bármi mást.

Válasz

A grep használata PCRE-vel:

$ grep -Po ".*(?=\s+[^\s]+$)" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

A GNU használata sed:

$ sed -r "s/(.*)\s+[^\s]+$/\1/" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Megjegyzések

  • @ramin biztos. .kérlek új kérdésként (ez az oldal így működik) 🙂
  • @ramin időbeli korlátozás vagy bármilyen figyelmeztetés?
  • azt állítja, hogy ez kizárt a szokásos kérdésben!
  • @ramin Ok .. vegye fel a kapcsolatot egy adminisztrátorral, lehet, hogy segíthetnek ebben. btw ellenőrzött valamilyen régi minőségbiztosítást a kérdésével kapcsolatban? annak lehetősége, hogy a kérdést már feltették és megválaszolták.
  • Ne ' ne tegyen szuper alapvető kérdéseket, például " hogyan tudok átnevezni egy fájlnevet Linux alatt ". Használja a Google-t.

Válasz

Perl használata:

perl -lane "$,=" ";pop(@F);print(@F)" in 

A rev + cut használata:

rev in | cut -d " " -f 2- | rev 

Válasz

A GNU sed használata:

sed -r "s/\s+\S+$//" input.txt 

Általánosabban ez az OSX BSD sedjével, valamint a GNU sed-kel működik:

sed "s/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//" input.txt 

Válasz

Ha az elválasztó mindig egyetlen karakter (tehát két vagy több egymást követő elválasztó üres mezőket jelöl meg), akkor head csak a beviteli fájl első sorát számolhatja meg, megszámolja az elválasztókat ( A n elválasztók azt jelenti, hogy a mezők száma n+1), majd a cut segítségével nyomtathat div id = “2bd300e77d”>

első mező a n mezőig (második az utolsóig), pl. tabulátorral tagolt bevitellel:

n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l) cut -f1-$n infile > outfile 

vagy pl. csv fájllal:

n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l) cut -d, -f1-$n infile > outfile 

Később futtatok néhány referenciaértéket, ha lesz rá időm, de hatalmas ráfordítással ezt gondolom A megoldásnak gyorsabbnak kell lennie, mint más, a regexet használó megoldásoknak, mivel ez minimális feldolgozást végez az első sorban a mezők számának megszerzéséhez, majd az ehhez a feladathoz optimalizált cut. / p>

Válasz

Hordozható módon ezek egyikét is használhatja:

sed "s/[[:space:]]*[^[:space:]]*$//" file awk "{sub(/[[:space:]]*[^[:space:]]*$/,"")}1" file 

Válasz

A vim használata:

Nyissa meg a fájlt a vimben

vim <filename> 

Ugrás az első sorra, arra az esetre, ha a kurzor bárhol máshol lenne.

gg 

Hozzon létre egy “q” nevű makrot qq, amely az aktuális sor hátuljára megy $, majd visszamegy az utolsó szóközhöz F (F nagybetű, majd szó szerinti szóköz), majd törölje az aktuális pozícióból a D lépjen le a következő sorra j és állítsa le a makrórögzítést a q gombbal.

qq$F Djq 

Most megismételhetjük makrónkat @q -vel minden sorhoz.
Megnyomhatjuk a @@ az utolsó makró megismétléséhez, vagy még egyszerűbb:

99@q 

a makró 99-szeresének megismétléséhez.
Megjegyzés: A szám nem egyezhet pontosan a sorokkal.

Válasz

Azok számára, akiknek hasonló problémájuk van, de különböző mezőelválasztókkal rendelkeznek, ez a awk metódus helyesen fogja megőrizni a mezőelválasztót:

$ cat file foo.bar.baz baz.bar.foo $ awk -F"." "sub(FS $NF,x)" file foo.bar baz.bar 

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük