Ich habe eine Textdatei in der ich die Felder 3,4,5 und 8 ausschneiden muss:
219 432 4567 Harrison Joel M 4540 Accountant 09-12-1985
219 433 4587 Mitchell Barbara C 4541 Admin Asst 12-14-1995
219 433 3589 Olson Timothy H 4544 Supervisor 06-30-1983
219 433 4591 Moore Sarah H 4500 Dept Manager 08-01-1978
219 431 4527 Polk John S 4520 Accountant 09-22-1998
219 432 4567 Harrison Joel M 4540 Accountant 09-12-1985
219 432 1557 Harrison James M 4544 Supervisor 01-07-2000
Da das Trennzeichen standardmäßig ein Tabulator ist, lautet der Befehl zum Extrahieren der Felder:
cut -f 3,4,5,8 filename
Die Sache ist, dass die Ausgabe mit dem ursprünglichen Dateiinhalt identisch ist. Was passiert hier? Warum funktioniert das nicht?
Antwort1
Nicht alle Leerzeichen zwischen den Spalten scheinen Tabulatoren zu sein, daher cut
können Sie nicht das erreichen, was Sie möchten. Ich würde awk
stattdessen vorschlagen, zu verwenden. Es ist flexibler als cut
beim Parsen von Datenspalten, wie Sie es erreichen möchten:
$ awk '{print $3,$4,$5,$8}' data.txt
Beispiel
$ awk '{print $3,$4,$5,$8}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
Sie können die Ausgabe auch mit dem column
folgenden Befehl strukturieren:
$ awk '{print $3,$4,$5,$8}' data.txt |column -t
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
Sie können alles auch einfach mit awk
und erledigen printf
:
$ awk '{printf "%s\t%-20s\t%s\n",$3,$4" "$5,$8}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
Schnitt überarbeitet
Die oben genannten Methoden funktionieren ganz gut, aber sie verarbeiten keine Zeilen, in denen der Wert für eine bestimmte Spalte Leerzeichen enthält. Beispielsweise wird die Zeile mit „Dept Manager“ auf „Dept“ gekürzt.
Wenn garantiert werden kann, dass die Daten die gezeigten Strukturen aufweisen, können wir sie verwenden, cut
aber statt sie anhand eines Trennzeichens aufzuteilen, können wir die Anzeige einfach anhand der tatsächlichen Positionen der Zeichen vornehmen.
Beispiel
Dadurch wird der Text aus der Datei ausgeschnitten data.txt
und die Positionen 9 bis 13 und 14 bis 35 usw. gedruckt.
$ cut -c 9-13,14-35,43-58 data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin Asst
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept Manager
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
awk erneut besucht
Awk kann auch so eingestellt werden, dass Text basierend auf seiner Position und nicht anhand eines Trennzeichens herausgezogen wird. Dies ist allerdings ausführlicher, aber der Vollständigkeit halber wird hier beschrieben, wie es geht.
$ awk '{
printf "%s\t%-20s\t%s\n",substr($0,9,5),substr($0,14,22),substr($0,43,16)
}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin Asst
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept Manager
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
awk FELDBREITEN
Wenn Sie eine Variante von GNU verwenden, awk
können Sie die Variable verwenden, FIELDWIDTHS
um die statische Größe jedes Felds anzugeben. Dies ist viel sauberer als die substr
Methode, wenn Sie darauf zugreifen können. Außerdem können Sie Felder effektiv zusammenfügen, die sonst als separate Felder analysiert würden.
$ awk 'BEGIN { FIELDWIDTHS="4 4 5 24 5 16 11" }{ print $3,$4,$5,$6 }' data.txt
4567 Harrison Joel M 4540 Accountant
4587 Mitchell Barbara C 4541 Admin Asst
3589 Olson Timothy H 4544 Supervisor
4591 Moore Sarah H 4500 Dept Manager
4527 Polk John S 4520 Accountant
4567 Harrison Joel M 4540 Accountant
1557 Harrison James M 4544 Supervisor
Antwort2
Ich vermute, dass es sich nicht um Tabulatoren handelt. Der Grund, warum ich nicht glaube, dass es sich um Tabulatoren handelt, ist, dass es anscheinend einwandfrei funktioniert, wenn ich die Datei kopiere und einfüge und die Felder manuell tabelliere . Wenn Sie die Felder und Werte nicht erneut tabellieren möchten , cut -f 3,4,5,8 filename
ist dies möglicherweise besser für Sie.cat filename | awk '{print $3, $4, $5, $8}'