it-swarm.com.de

so entfernen Sie die ersten beiden Spalten einer Datei mit Shell (awk, sed, was auch immer)

Ich habe eine Datei mit vielen Zeilen. In jeder Zeile gibt es viele Spalten (Felder), die durch Leerzeichen getrennt sind. Die Anzahl der Spalten in jeder Zeile ist unterschiedlich. Ich möchte die ersten beiden Spalten entfernen. .wie man?

64
wenzi

Sie können es mit cut machen:

cut -d " " -f 3- input_filename > output_filename

Erklärung:

  • cut: Rufen Sie den Ausschneidebefehl auf
  • -d " ": Verwenden Sie ein einzelnes Leerzeichen als Trennzeichen (cut verwendet standardmäßig TAB).
  • -f: Geben Sie die zu speichernden Felder an
  • 3-: alle Felder, die mit Feld 3 beginnen
  • input_filename: Verwenden Sie diese Datei als Eingabe
  • > output_filename: Schreibe die Ausgabe in diese Datei.

Alternativ können Sie es auch mit awk machen:

awk '{$1=""; $2=""; sub("  ", " "); print}' input_filename > output_filename

Erklärung:

  • awk: Ruft den Befehl awk auf
  • $1=""; $2="";: Setzen Sie Feld 1 und 2 auf die leere Zeichenfolge
  • sub(...);: Bereinigen Sie die Ausgabefelder, da die Felder 1 und 2 weiterhin durch "" begrenzt werden.
  • print: druckt die modifizierte Zeile
  • input_filename > output_filename: wie oben.
130
sampson-chen

Hier ist eine Möglichkeit, mit Awk relativ leicht zu verstehen:

awk '{print substr($0, index($0, $3))}'

Dies ist ein einfacher awk-Befehl ohne Muster. Die Aktion in {} wird für jede Eingabezeile ausgeführt. 

Die Aktion besteht darin, die Teilzeichenfolge einfach mit der Position des dritten Felds zu drucken.

  • $0: die gesamte Eingabezeile
  • $3: 3. Feld
  • index(in, find): gibt die Position von find in String in zurück
  • substr(string, start): Rückgabe eines Teilstrings ab Index start

Wenn Sie ein anderes Trennzeichen verwenden möchten, z. B. Komma, können Sie es mit der Option -F angeben:

awk -F"," '{print substr($0, index($0, $3))}'

Sie können dies auch für eine Teilmenge der Eingabezeilen ausführen, indem Sie vor der Aktion in {} ein Muster angeben. Nur die Zeilen, die dem Muster entsprechen, lassen die Aktion ausführen.

awk 'pattern{print substr($0, index($0, $3))}'

Wo Muster sein kann, wie:

  • /abcdef/: regulären Ausdruck verwenden, wird standardmäßig für $ 0 verwendet.
  • $1 ~ /abcdef/: bearbeitet ein bestimmtes Feld.
  • $1 == blabla: Stringvergleich verwenden
  • NR > 1: Datensatz-/Zeilennummer verwenden
  • NF > 0: Feld-/Spaltennummer verwenden
21
raychi

Vielen Dank, dass Sie die Frage gestellt haben. Ich möchte auch das Skript hinzufügen, das mir geholfen hat.

awk '{ $1=""; print $0 }' file
12
Felipe Alvarez
awk '{$1=$2="";$0=$0;$1=$1}1'

Eingang

a b c d

Ausgabe

c d
8
Steven Penny

Es ist ziemlich einfach, dies nur mit Shell zu tun

while read A B C; do
echo "$C"
done < oldfile >newfile
6
technosaurus

Sie können sed verwenden:

sed 's/^[^ ][^ ]* [^ ][^ ]* //'

Dies sucht nach Zeilen, die mit einem oder mehreren Nicht-Leerzeichen, einem Leerzeichen, einem weiteren Satz von Ein oder Mehrfach-Nicht-Leerzeichen und einem weiteren Leerzeichen beginnen, und löscht das übereinstimmende Material, dh die ersten beiden Felder. [^ ][^ ]* ist geringfügig kürzer als die äquivalente, aber explizitere [^ ]\{1,\}-Notation, und die zweite könnte Probleme mit GNU sed haben (wenn Sie jedoch --posix als Option verwenden, kann selbst GNU sed es nicht schrauben oben). OTOH: Wenn die zu wiederholende Zeichenklasse komplexer war, gewinnt die nummerierte Notation an Bedeutung. Es lässt sich leicht erweitern, um 'Leerzeichen oder Tabulatoren' als Trennzeichen oder 'Mehrfach-Leerzeichen' oder 'Mehrfach-Leerzeichen oder Tabulatoren' zu behandeln. Es kann auch modifiziert werden, um optionale führende Leerzeichen (oder Tabulatoren) vor dem ersten Feld usw. zu behandeln.

Für awk und cut siehe Sampson-Chen 's answer . Es gibt andere Möglichkeiten, das Skript awk zu schreiben, aber sie sind nicht wesentlich besser als die gegebene Antwort. Beachten Sie, dass Sie das Feldtrennzeichen in awk möglicherweise explizit festlegen müssen (-F" "), wenn Sie nicht möchten, dass Registerkarten als Trennzeichen behandelt werden oder wenn zwischen den Feldern mehrere Leerzeichen vorhanden sind. Der POSIX-Standard cut unterstützt nicht mehrere Trennzeichen zwischen Feldern. GNU cut verfügt über die nützliche, aber nicht standardmäßige -i-Option, um mehrere Trennzeichen zwischen Feldern zu ermöglichen.

Sie können es auch in reiner Shell tun:

while read junk1 junk2 residue
do echo "$residue"
done < in-file > out-file
6

Perl:

Perl -lane 'print join(' ',@F[2..$#F])' File

awk:

awk '{$1=$2=""}1' File
4
Vijay

Das könnte für Sie funktionieren (GNU sed):

sed -r 's/^([^ ]+ ){2}//' file

oder für Spalten, die durch ein oder mehrere Leerzeichen getrennt sind:

sed -r 's/^(\S+\s+){2}//' file
1
potong

Durch die Verwendung von awk und basierend auf einigen der folgenden Optionen wird die Verwendung einer for-Schleife etwas flexibler. Manchmal möchte ich vielleicht die ersten 9 Spalten löschen (wenn ich zum Beispiel ein "ls -lrt" mache), also ändere ich die 2 gegen eine 9 und das wars:

awk '{ for(i=0;i++<2;){$i=""}; print $0 }' your_file.txt

0
Carlos

Verwenden Sie kscript

kscript 'lines.split().select(-1,-2).print()' file
0
Holger Brandl