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