Ich versuche, mithilfe eines Bash-Skripts eine Textverarbeitung für eine Datei durchzuführen. Ziel ist es, alle Zeilen, die mit „field:“ beginnen und unter der Bezeichnung „attribute:“ eingerückt sind, mit der zugehörigen Zeile zu ersetzen, die mit „- attr:“ beginnt und folgt.
Bisher glaube ich, dass ich Regex-Muster habe, die mit den Beschriftungen übereinstimmen sollten:
/ *field:(.*)/g
/ *- attr:(.*)/g
Aber ich hatte keinen Erfolg mit der Logik, die gewünschten Felder zu analysieren und sie richtig zu vertauschen.
Beispiel-Eingabetext
- metric: 'example.metric.1'
attributes:
field: 'example 1'
- attr: 'example1'
field: 'example 2'
- attr: 'example2'
field: 'example 3'
- attr: 'example3'
field: 'example 4'
- attr: 'example4'
- metric: 'example.metric.2'
attributes:
field: 'example 5'
- attr: 'example5'
field: 'example 6'
- attr: 'example6'
field: 'example 7'
- attr: 'example7'
- metric: 'example.metric.3'
...
Gewünschte Ausgabe
- metric: 'example.metric.1'
attributes:
- attr: 'example1'
field: 'example 1'
- attr: 'example2'
field: 'example 2'
- attr: 'example3'
field: 'example 3'
- attr: 'example4'
field: 'example 4'
- metric: 'example.metric.2'
attributes:
- attr: 'example5'
field: 'example 5'
- attr: 'example6'
field: 'example 6'
- attr: 'example7'
field: 'example 7'
- metric: 'example.metric.3'
...
Wie würde ich das erreichen?
Antwort1
Verwenden eines beliebigen awk in einer beliebigen Shell auf jeder Unix-Box:
$ awk '$1=="field:"{s=ORS $0; next} {print $0 s; s=""}' file
- metric: 'example.metric.1'
attributes:
- attr: 'example1'
field: 'example 1'
- attr: 'example2'
field: 'example 2'
- attr: 'example3'
field: 'example 3'
- attr: 'example4'
field: 'example 4'
- metric: 'example.metric.2'
attributes:
- attr: 'example5'
field: 'example 5'
- attr: 'example6'
field: 'example 6'
- attr: 'example7'
field: 'example 7'
- metric: 'example.metric.3'
Wenn Ihnen nach einigen Zeilen ein Leerzeichen fehlt field:
oder Sie aus irgendeinem Grund unbedingt einen regulären Ausdruck verwenden möchten, ändern Sie ihn $1=="field:"
in $1~/^field:/
oder /^[[:space:]]*field:/
, je nachdem, was Sie bevorzugen.
Antwort2
Mit sed
:
sed -n '/^ *field: /{h;n;G};p' data
Wenn ein Schlüsselwort übereinstimmt field
, dann:
- speichert die aktuelle Zeile im
hold space
(h
) - Holen Sie sich die nächste Zeile aus der Datei im
pattern space
(n
) - vertausche das
pattern space
mit demhold space
(G
) (entspricht Zeilentausch)
Drucken Sie jede Zeile aus, die Sie finden:p
Antwort3
Verwendung von awk
:
awk '{if ($1 == "field:") {a=$0;x=0}
else if (/- attr:/) {$0 = $0 ORS a; x=1} else {x=1}}x' input
Wenn in diesem Befehl field:
gefunden wird, wird der aktuelle Eingabedatensatz ( $0
) in der Variable gespeichert a
und x wird auf Null gesetzt. Und wenn attr:
gefunden wird, $0
wird d in alt geändert, $0
gefolgt von ORS
(neue Zeile), gefolgt von der Variable a
.
Antwort4
Wir können POSIX-Sed-Konstrukte verwenden, um die besagten Zeilen umzudrehen.
sed '/attr:/!x;$G' file