Ich habe eine Ausgabe des Unix-Befehls uniq -c, die die Anzahl der Vorkommen einer Zeichenfolge am Anfang jeder Zeile druckt. Die Zeichenfolge stellt zwei Autoren dar, die durch eine Pipe getrennt sind (z. B. Aabdel-Wahab S|Abdel-Hafeez EH).

  1 Aabdel-Wahab S|Abdel-Hafeez EH
  1 Aabdel-Wahab S|Abdulla AM
  4 Aabdel-Wahab S|Ahmad AK
  1 Aabdel-Wahab S|Mosalem FA
  1 Aabye MG|Andersen AB
  8 Aabye MG|Changalucha J
  1 Aabye MG|Christensen DL
  1 Aabye MG|Faurholt-Jepsen D

Ich muss die Vorkommensnummer erfassen und an das Ende der Zeile verschieben. Zum Beispiel:

Aabdel-Wahab S|Abdel-Hafeez EH|1
Aabdel-Wahab S|Abdulla AM|1
Aabdel-Wahab S|Ahmad AK|4
Aabdel-Wahab S|Mosalem FA|1
Aabye MG|Andersen AB|1
Aabye MG|Changalucha J|8
Aabye MG|Christensen DL|1
Aabye MG|Faurholt-Jepsen D|1

Bitte beachten Sie, dass die Frequenzen jetzt durch Pipe getrennt sind. Unten ist mein Einzeiler in Awk eingefügt:

awk '{num=$1;$1=""; sub(/^ /,""); print $0,"|",num;}' file

Die Awk fügen jedoch zusätzliche Leerzeichen um die endgültige Pipeline hinzu:

Aabdel-Wahab S|Abdel-Hafeez EH | 1
Aabdel-Wahab S|Abdulla AM | 1
Aabdel-Wahab S|Ahmad AK | 4
Aabdel-Wahab S|Mosalem FA | 1
Aabye MG|Andersen AB | 1
Aabye MG|Changalucha J | 8
Aabye MG|Christensen DL | 1
Aabye MG|Faurholt-Jepsen D | 1

Irgendeine Idee, wie man vorgeht (nicht notwendig mit Awk)?

0
Andrej 17 Apr. 2018 im 13:26

4 Antworten

Beste Antwort

Sie können printf verwenden:

awk '{num=$1;$1=""; sub(/^ /,""); printf("%s|%s\n",$0,num);}' file
1
llllllllll 17 Apr. 2018 im 10:34

Dies ist ein wahrer Fall für die Verwendung von sed anstelle von awk:

sed 's/^  *\([0-9][0-9]*\) *\(.*\)/\2|\1/' file

Regex-Aufschlüsselung:

  • ^ * Beginnen Sie mit mindestens einem Leerzeichen
  • \( Beginn der Erfassung der ersten Gruppe
    • [0-9][0-9]* Entspricht mindestens einer Ziffer
  • \) Ende von CG eins
  • * Beliebig viele Leerzeichen
  • \(.*\) Rest der Eingabezeile erfassen (CG zwei)

Die Ersetzungszeichenfolge ändert die Reihenfolge der Erfassungsgruppen mit einem einzelnen | zwischen.

2
revo 17 Apr. 2018 im 11:12

Awks, die keine Leerzeichen hinzufügen, sagen awk, dass sie Leerzeichen hinzufügen sollen. Was bedeutet , Ihrer Meinung nach in print 1,2 (Hinweis: Suchen Sie in der awk-Manpage nach OFS)? Tu das einfach nicht:

awk '{num=$1; $1=""; sub(/^ /,""); print $0 "|" num}' file
2
Ed Morton 17 Apr. 2018 im 11:53

Verwenden von sed:

sed -r 's/\s*([0-9]+)\s*(.*)/\2|\1/' infile
  • Das \s* entspricht null oder mehr Leerzeichen.
  • Das ([0-9]+) stimmt mit einer oder mehreren Ziffern und Klammern überein, die für die Gruppenübereinstimmung verwendet werden.
  • Das (.*) stimmt mit allem überein und Klammern, die für die Gruppenübereinstimmung verwendet werden, stimmen auch hier wieder überein.
  • In \2|\1 drucken wir die zweite Gruppenübereinstimmung, d. H. (.*), die nächste erste Gruppenübereinstimmung, d. H. ([0-9]+) mit Pipe dazwischen.

POSIXly würden Sie tun:

sed 's/^ *\([0-9][0-9]*\) *\(.*\)$/\2|\1/' infile
1
αғsнιη 17 Apr. 2018 im 11:16