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
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;1fá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
cutúgy hangzik, mint a munka eszköze.