Wie schneide ich ein Feld aus einer Textzeile ab, die am Ende zählt?


32

Ich kann ein Feld aus einer Zeile mit dem Befehl "Ausschneiden" auswählen. Zum Beispiel mit folgenden Daten:

a,b,c,d,e
f,g,h,i,j
k,l,m,n,o

Dieser Befehl:

cut -d, -f2 # returns the second field of the input line

Kehrt zurück:

b
g
l

Meine Frage: Wie kann ich die zweite Feld wählen Zählen vom Ende? Im vorherigen Beispiel wäre das Ergebnis:

d
i
n

Antworten:


52

Kehre die Eingabe vorher und nachher um cutmit rev:

<infile rev | cut -d, -f2 | rev

Ausgabe:

d
i
n

1
Ich habe viele kleine Schnipsel in meinem Bin-Ordner. rcut ist genau dafür: #! / bin / bash rev | "$ @" ausschneiden | rev
John Allsup

2
Es ist schade, dass cutkeine negativen Feldindizes (wie Python) akzeptiert werden können.
Keith Devens

10

Versuchen Sie dies mit :

awk -F, '{print $(NF-1)}' file.txt

Oder mit :

perl -F, -lane 'print $F[-2]' file.txt

Oder mit (danke manatwork):

ruby -F, -lane 'print $F[-2]' file.txt

Oder mit bash(danke manatwork):

while IFS=, read -ra d; do echo "${d[-2]}"; done < file.txt

Oder mit :

cat file.txt |
python -c $'import sys\nfor line in sys.stdin:\tprint(line.split(",")[-2])'

1
bashbraucht nicht festgelegt Spaltenanzahl für diese: while IFS=, read -ra d; do echo "${d[-2]}"; done < file.txt.
Manatwork

1
BTW, Ihre dritte Lösung funktioniert auch , wenn Sie ändern perlmit ruby.
Manatwork

Danke, rubyhinzugefügt, bashbearbeitet.
Gilles Quenot

1
Wenn das vierte Feld möglicherweise mit -oder beginnt (abhängig von der Umgebung, der Shell oder der Art und Weise, in der die Shell kompiliert wurde) und möglicherweise Backslash-Zeichen enthält, echoist dies keine Option. Warum müssen Sie vor dem Füttern mit nichtscat konzen trieren ? Du brauchst statt in und . Negative Indizes funktionieren nur in neueren Versionen von und . In älteren Versionen können Siefile.txtpythonread -Aread -aksh93zshzshksh93bash${d: -2:1}
Stéphane Chazelas

2
@StephaneChazelas, ich denke du meinst ${d[@]: -2:1}in deinem letzten Satz.
Manatwork

0

Sed verwenden:

sed -E 's/^([^,]*,)*([^,]*)(,[^,]*){1}$/\2/' infile

Ausgabe:

d
i
n

Erläuterung

  • ([^,]*,)* Entspricht einer beliebigen Anzahl von Nicht-Komma-Zeichen, gefolgt von einem Komma, dh einer beliebigen Anzahl von Spalten.
  • ([^,]*) stimmt mit einer Spalte überein.
  • (,[^,]*){1}Stimmt mit einer Spalte am Ende überein, wenn Sie den Quantifizierer so ändern {1}, dass {2}er mit der zweiten Spalte am Ende übereinstimmt.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.