私は、bash スクリプトを使用して、ファイルに対してテキスト処理を実行しようとしています。目標は、'attribute:' ラベルの下にインデントされた "field:" で始まるすべての行を取得し、それに続く "- attr:" で始まる関連行と交換することです。
これまでのところ、ラベルに一致する正規表現パターンがあると思います。
/ *field:(.*)/g
/ *- attr:(.*)/g
しかし、必要なフィールドを解析して正しく交換するロジックでは成功しませんでした。
入力テキストの例
- 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'
...
望ましい出力
- 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'
...
これを実現するにはどうしたらいいでしょうか?
答え1
あらゆる Unix ボックス上のあらゆるシェルで awk を使用する:
$ 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'
いくつかの行の後にスペースがない場合field:
、または何らかの理由でどうしても正規表現を使用したい場合は、またはのいずれか好みに応じて$1=="field:"
に変更します。$1~/^field:/
/^[[:space:]]*field:/
答え2
とsed
:
sed -n '/^ *field: /{h;n;G};p' data
キーワードが一致する場合field
:
- 現在の行を
hold space
(h
)に保存する pattern space
(n
)内のファイルから次の行を取得します。- を( )
pattern space
と入れ替える(行の入れ替えと同じ)hold space
G
遭遇した各行を出力します。p
答え3
使用方法awk
:
awk '{if ($1 == "field:") {a=$0;x=0}
else if (/- attr:/) {$0 = $0 ORS a; x=1} else {x=1}}x' input
このコマンドでは、field:
が見つかった場合、現在の入力レコード ( $0
) が変数に保存されa
、 x がゼロに設定されます。attr:
が見つかった場合、$0
は old に変更され、$0
その後にORS
(改行)、その後に変数が続きますa
。
答え4
POSIX sed 構造を使用して、上記の行を反転することができます。
sed '/attr:/!x;$G' file