実行後、次の結果が出力されますdiff
。
< #R1#Number = Gauge32: 258 Name = STRING: "TATA"
---
> #R1#Number = Gauge32: 280 Name = STRING: "TATA"
次の出力を得るには、シェルスクリプトでsedコマンドを実装する必要があります。
Hostname=R1; old=258 new=280, Name="TATA"
答え1
この試み:
diff ... | sed -n -e '
/^< / h
/^---/ H
/^> / { H; x; s/\n//g;
s/^< #\([^#][^#]*\)#Number = Gauge32: \([0-9][0-9]*\) .* #\1#Number = Gauge32: \([0-9][0-9]*\) .* Name = STRING: \("[^"]*"\).*/Hostname=\1; old=\2 new=\3, Name=\4/;
p; }'
すべてを一行に配置し、興味深いものだけを選択するのがアイデアです。
詳細:
sed -n
- 基本的に何も印刷しない/^< / h
- 出発線を<
予約されたスペースにコピーしてください。/^---/ H
---
- 予約済みスペースに次の行を追加します。/^> / { ... }
->
次から始まる行の場合:H
- 予約済みスペースに行を追加x
- 保有空間とパターン空間を交換s/\n//g
- 改行文字を削除すると、パターンスペースに次の内容が含まれます。< #R1#Number = Gauge32: 258 Name = STRING: "TATA"---> #R1#Number = Gauge32: 280 Name = STRING: "TATA"
s/.../.../
- フォーマットされた出力(ここには特別な内容はありません。ただsed
-fu)p
- 印刷
diff
隣接する行が変更される可能性があるため、通常の出力には機能しません。しかしそれはあなたが尋ねたように質問に答えます。
答え2
Perlを試してみることもできます。
diff file1 file2 |
perl -lne 'if(/^(.).*?#(.+?)#.*?:\s*(\d+).*(".+?")/){
$1 eq ">" ? print "Hostname=$2; old=$o new=$3, Name=$4" : ( $o=$3 )}'
説明する
- 各呼び出しに改行文字を追加し、
-l
指定されたスクリプトが入力ファイルの各行に適用されるようにします。print
-n
-e
- 正規表現は、最初の文字()、
^.
間の最初の文字列()、その後にゼロ個以上の空白と数字のセット()、行で最後に引用された文字列()を認識します。角かっこを使用すると、これらの内容が保存されます。#
#(.+?)#
:
:\s*(\d+)
.*(".+?")
$1
$4
foo ? bar : baz
: これは多くの言語で見られる C 構文です。 「fooが真であればbarをし、そうでなければbazをしなさい」の略です。したがって、$1
前の一致ジョブとして保存された行の最初の文字があれば>
印刷し、それ以外の場合は一致する3番目のパターンをとして保存します$o
。
または
diff file1 file2 |
perl -lane '$o = $F[4] if /^</; $F[1]=~s/#(.*)#.*/$1/;
print "Hostname=$F[1]; old=$o new=$F[4], Name=$F[8]" if />/'
説明する
- これにより、Perlは各入力行を空白に自動的に分割して配列
-a
に保存します。@F
$o = $F[4] if /^</;
:5番目のフィールドが$o
その行の最初の文字であるかのように保存されます<
。$F[1]=~s/#(.*)#.*/$1/;
:2番目のフィールド($F[1]
0から始まる配列番号)から、ホスト名を除くすべてのエントリが削除されます。