it-swarm.com.de

So löschen Sie die letzte Spalte einer Datei unter Linux

Ich möchte die letzte Spalte einer txt-Datei löschen, obwohl ich die Spaltennummer nicht kenne. Wie könnte ich das machen?

Beispiel:

Eingang:

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

Und ich möchte, dass meine Ausgabe ist:

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

Mit awk:

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

oder:

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

oder:

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

Obwohl dies wie Voodoo aussieht, funktioniert es. Jeder dieser awk-Befehle besteht aus drei Teilen.

Das erste ist NF, was eine Voraussetzung für den zweiten Teil ist. NF ist eine Variable, die die Anzahl der Felder in einer Zeile enthält. In AWK sind die Dinge wahr, wenn sie nicht 0 oder eine leere Zeichenfolge "" Sind. Daher geschieht der zweite Teil (wobei NF dekrementiert wird) nur, wenn NF nicht 0 ist.

Der zweite Teil (entweder NF-=1NF-- Oder --NF) Subtrahiert nur einen von der Variablen NF. Dies verhindert, dass das letzte Feld gedruckt wird, da beim Ändern eines Felds (in diesem Fall Entfernen des letzten Felds) awk$0 Neu konstruieren und standardmäßig alle durch Leerzeichen getrennten Felder verketten. $0 Enthielt nicht mehr das letzte Feld.

Der letzte Teil ist 1. Es ist nicht magisch, es wird nur als Ausdruck verwendet, der true bedeutet. Wenn ein awk -Ausdruck ohne zugehörige Aktion als wahr ausgewertet wird, lautet die Standardaktion awkprint $0.

43
cuonglm

Verwenden von grep mit PCRE:

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

Verwenden von GNU sed:

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

Verwenden von Perl:

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

Verwenden von rev + cut:

rev in | cut -d ' ' -f 2- | rev
14
kos

Verwenden von GNU sed:

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

Im Allgemeinen funktioniert dieser mit dem BSD sed in OSX sowie GNU sed:

sed 's/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//' input.txt
5
Digital Trauma

Portabel können Sie eine der folgenden verwenden:

sed 's/[[:space:]]*[^[:space:]]*$//' file

awk '{sub(/[[:space:]]*[^[:space:]]*$/,"")}1' file
1
Ed Morton

Wenn das Trennzeichen immer ein einzelnes Zeichen ist (zwei oder mehr aufeinanderfolgende Trennzeichen kennzeichnen leere Felder), können Sie head nur die erste Zeile Ihrer Eingabedatei verwenden und die Trennzeichen zählen (n Trennzeichen bedeuten Zahl von Feldern ist n+1), dann verwenden Sie cut, um vom 1 st-Feld bis zum n -ten Feld (vorletztes Feld) zu drucken, z mit tabulatorgetrennten Eingaben:

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

oder z.B. mit einer csv Datei:

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

Ich werde später einige Benchmarks ausführen, wenn ich Zeit habe, aber mit großem Aufwand denke ich, dass diese Lösung schneller sein sollte als andere Lösungen, die Regex verwenden, da diese in der ersten Zeile nur eine minimale Verarbeitung durchführt, um die Nr. Zu erhalten. von Feldern und verwendet dann cut, das für diesen Job optimiert ist.

1
don_crissti

Für Personen, die ein ähnliches Problem haben, aber unterschiedliche Feldtrennzeichen haben, behält diese awk -Methode das Feldtrennzeichen korrekt bei:

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

Verwenden von vim:

Datei in vim öffnen

vim <filename> 

Gehen Sie zur ersten Zeile, nur für den Fall, dass sich der Cursor an einer anderen Stelle befindet.

gg

Erstellen Sie ein Makro mit dem Namen "q" qq, das am Ende der aktuellen Zeile $ Und dann am letzten Leerzeichen F (Großbuchstabe F, gefolgt von einem Literal) steht LEERTASTE) dann von der aktuellen Position bis zum Ende der Zeile D löschen, zur nächsten Zeile j gehen und die Makroaufzeichnung mit q beenden.

qq$F Djq

Jetzt können wir unser Makro mit @q Für jede Zeile wiederholen.
Wir können auch @@ Drücken, um das letzte Makro zu wiederholen oder noch einfacher:

[email protected]

um das Makro 99 Mal zu wiederholen.
Hinweis: Die Nummer darf nicht genau mit den Zeilen übereinstimmen.

0
cee