最短の行の長さまでの違いのみを出力する、任意の 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 番目のコマンドは待機します。