Wie verwende ich ^ # $ als Datensatztrennzeichen in awk?

8

Wie weist man awk an, ein #Zeichen in einer Zeile als Datensatztrennzeichen zu verwenden? Das Problem ist, dass Sie nicht sagen können, RS="^#$"weil es ^mit dem Anfang der Datei und nicht mit dem Anfang einer Zeile RS="#\n"übereinstimmt und auch nicht funktioniert, weil es mit #Zeichen übereinstimmt , die nicht am Anfang einer Zeile stehen.

$ data='#
first record, first field
first record, second field
#
second record, first field#
second record, second field
'

Drucken Sie dann das erste Feld jedes Datensatzes mit RS="#\n":

$ printf "%s" "$data" | awk '
  BEGIN { RS="#\n"; FS="\n" }
  /./ {print $1}
  '
first record, first field
second record, first field
second record, second field

Die letzte Zeile ist falsch, weil es nicht das erste Feld ist, sondern das zweite. Die beabsichtigte Ausgabe war

first record, first field
second record, first field#
Ernest A.
quelle
1
Könnten Sie bitte auch ein Beispiel für die Ausgabe geben, die Sie benötigen
Roaima
So sehen Ihre Daten aus line one#line two#line three?
Skaperen
und RS="#"was?
Skaperen
@Skaperen nein, die Daten sehen so aus #\nrecord one\n#\nrecord twound jeder Datensatz besteht aus mehreren \ngetrennten Feldern.
Ernest A
RS='#\n'sollte afaik funktionieren - obwohl es die Initiale #so behandelt, als würde ein leerer Datensatz beendet (dh alle NRWerte werden um eins "aus" sein)
steeldriver

Antworten:

6

Hier ist eine Möglichkeit, dies zu tun awk:

$ printf "%s\n" "$data" | 
    awk -F'\n' -v RS='(^|\n)#\n' '/./ {print $1}' 
first record, first field
second record, first field#

Der Trick besteht darin, das Datensatztrennzeichen entweder auf den Anfang der Datei ( ^) oder auf eine neue Zeile zu setzen, gefolgt von einer #und einer weiteren neuen Zeile \n.


terdon
quelle
1
Beachten Sie die NRs wird einmalig in diesem Fall (versuchen Sie ersetzen /./mit NR==1). Ich denke, die einfachste Lösung wäre, die Datei / Daten mit einem #in einer separaten Zeile zu beenden - anstatt zu beginnen . Dann \n#\nkönnte als RS verwendet werden und es würde richtig funktionieren.
don_crissti
@don_crissti Ich habe das gerade aus dem OP kopiert. Ich gehe davon aus, dass sie es verwenden, um Leerzeilen zu vermeiden, NR==1und funktionieren daher nicht, wenn weiter unten mehr Leerzeilen vorhanden sind.
Terdon