複数回繰り返される一連の行を含むテキストファイルがあります。たとえば、
param id: 0
value: 2
description: "hello"
param id: 1
value: 3
description: "world"
引っ越したい説明する以上値そして変化パラメータIDより高い値で、例えばパラメータID0の代わりに1.これを行うためにスクリプトを使用したいと思います。誰もがこれを実行できるコマンドで私を助けることができますか?
答え1
@MelBursianがすでにコメントで提案したように、私もawk
同意しますsed
。
awk '
BEGIN { OFS=FS=": " }
{
if ($1 == "param id") {
$2 += 1;
}
if ($1 == "value") {
val=$0; getline;
print; print val;
next;
}
print;
}
' file
答え2
これにより、「value:」で始まるすべての行が対応する次の行に切り替わります。
sed '/^value: /{N;s/^\(.*\)\n\(.*\)$/\2\n\1/}'
説明する:
/^value: / { ... }
...
中括弧で囲まれたコマンドは、正規表現 "^value:" (ここでは偽) と一致する行に対してのみ実行されます。N
パターン空間に次の行を追加します。したがって、ここでは改行文字で連結された2行を操作できます。s/^\(.*\)\n\(.*\)$/\2\n\1/
改行文字の前のテキストと改行文字の後のテキストを切り替えます。s/something/else/
「something」を「else」に置き換える代替コマンドです。^\(.*\)\n\(.*\)$
パターンスペースの先頭から改行文字までのすべてのテキストを一致させ、それを式1として保存します。次に、パターン空間の終わりまでの他のすべての文字が式2として記憶される。\2\n\1
式 2 の後に改行文字が続き、次に式 1 が置換に使用されます。
答え3
sed
価値を追加するために使用することは強くお勧めしません。このタイプの作業には適切なツールではありません。ただし、必要がある場合はsed
これはGNUでのみ機能しますsed
。
sed -rn '/^param/{s/(.*)([0-9]+)/echo \1$((\2+1))/e;p;n;h;n;p;x;p;n;p}' file
-r
拡張正規表現を有効にします。-n
sed
自動印刷を無効にしました。/^param/
パターンで始まる行を検索しますparam
。s/(.*)([0-9]+)/echo \1$((\2+1))/e
さて、その行で検索/置換してください。番号を検索して([0-9]+)
交換してecho \1$((\2+1))
実行します。e
in はs///e
シェルで一致するパターンを実行する修飾子です。p;
次に、変更された行を印刷します。n;
パターン空間に次の行(行)をロードしますvalue
。h;
行を予約済みスペースにコピーします。n;p;
次の行(このdescription
行)をロードして印刷します。x;
モードを変更してスペースを保ちます。p;
この行を印刷してください。n;p
次の行(空白行)をロードして印刷します。
サンプル入力として出力:
param id: 1
description: "hello"
value: 2
param id: 2
description: "world"
value: 3
答え4
線の移動はPOSIXを使用して実行するのが最も簡単ですex
。数値増分を実行するのが最も簡単ですawk
。幸いex
、外部ツールを使用して特定の行をフィルタリングできます。
printf %s\\n 'g/description/m-2' 'g/param id/.!awk "++\$NF"' x | ex file
英語に翻訳すると、最初のコマンドは「説明」という単語を含むすべての行を1行に移動します。
(そこに2がある理由は、文字通り翻訳すると「この行を2行の後ろの点に移動」するためです。)
2番目は、「param id」を含むすべての行をフィルタリングすることですawk
。
コマンドはawk
「行の最後のフィールドをインクリメントし、結果が正確にゼロでない限り行を印刷します。:)」です。
x
「保存後終了」です。