3

最短の行の長さまでの違いのみを出力する、任意の bash ストリームで使用できる diff ラッパーが必要です。これは通常のファイルの場合は簡単で、2 回読み取るだけです。

~/bin/mindiff:
min=$(calc -p 'min(' $(wc -l < "$1") ', ' $(wc -l < "$2") ')')
diff <(head -$min "$1")  <(head -$min "$2")

(これは、実行中のテキスト処理出力の違いを確認するのに非常に便利です。)

:行ごとの差分は必要ありません。上記のスクリプトが行うこと (複数行にまたがる差分を許可する) が必要ですが、ストリームで作業しています。あるストリーム/ファイルが他のストリーム/ファイルよりも長いために発生する、下部の混乱を望んでいません。-B1、-y --suppress-common-lines -W180、dwdiff にパイプされた -U1 などの通常の diff オプションを渡すことができるように、通常の diff を呼び出すことをお勧めします。

ただし、これを任意のストリームで呼び出して、一度だけ読み取れるようにしたいと思います。

mindiff <(sed 's/fluff//' /tmp/out) <(ssh server sed 's/fluff//' /tmp/out)

いくつかの #bash ウィザードの助けを借りて、この awk ヘルパーを取得しました。この awk ヘルパーは、一方が終了するまで 2 つのストリームを並行して読み取り、それに対して diff を実行します。

mkfifo a b

awk '
BEGIN{ f2=ARGV[2];ARGC-- }
( (getline line <f2)>0 ) { print > "a"; print line > "b" }
' "$1" "$2" &

diff a b

完全なスクリプト

短いおもちゃの例では機能しますが、次のようなものを試してみると

mindiff <(yes |head -40000) <(yes |head -40000)

ハングするだけです。「print NR;」の追加 awk を実行すると、36865 行まで移動することが示されます (10533 まで移動するため、<(yes yesyes)行数に関係なく、特定のバイト数が許可されているようです)。

すべての行で awk をフラッシュするように追加system("")すると、さらに早く停止します (34818 行目)。

私の差分を妨げているのは何ですか?

更新: 私の疑いではdiff a b、a と b が大きい場所で実行すると、diff は a からの行の束を要求し、次に b からの束を要求します。ヘルパー スクリプトは並行して行を提供するだけなので、1 行を a にプッシュし、次に 1 行を b にプッシュしようとしますが、diff は a からさらに多くの行を要求している最中であるため、b へのプッシュはハングします。ただし、定期的に実行する場合diff <(cmd) <(cmd)、最初の cmd は一連の行をプッシュできますが、2 番目のコマンドは待機します。

4

2 に答える 2

0

別のオプションは、差分出力を単純に解析し、下部の綿毛を削除することです。残念ながら、これが最も簡単なようです。たとえば、-u と通常の diff 出力の両方を処理するには:

diff "$@" "$if1" "$if2" | awk '
lines && /^@@ -[0-9]*,[0-9]* \+[0-9]*,[0-9]* @@$/ {print lines; lines=""}
lines && /^[0-9]+,[0-9]+d[0-9]+$/ {print lines; lines=""}
// {if(lines)lines=lines"\n"$0; else lines=$0}
'

-y を扱うには、もう少し作業が必要です。それはあまり満足のいく解決策ではありません。

于 2013-06-11T11:43:21.780 に答える