ファイルのdiff3に違いが見つかりませんでした。
$ grep -P '\[\[.*?\]\]' -o intro.tex | sort > A.txt
$ grep -P '\[\[.*?\]\]' -o intro.tex | sort | uniq > B.txt
$ grep '\\pnum %% \[\[' intro.tex | sed 's/\\pnum %% //' | sort > C.txt
$ diff3 A.txt B.txt C.txt | wc -l
0
diff3 は、同じコマンドを実行するプロセス置換に違いを見つけました。
$ diff3 \
<(grep -P '\[\[.*?\]\]' -o intro.tex | sort) \
<(grep -P '\[\[.*?\]\]' -o intro.tex | sort | uniq) \
<(grep '\\pnum %% \[\[' intro.tex | sed 's/\\pnum %% //' | sort) | wc -l
95
なぜ?どんなアイデアがありますか?
最小再生:
$ echo test > a
$ diff3 a a a
$ diff3 <(cat a) <(cat a) <(cat a)
====1
1:1c
test
2:0a
3:0a
答え1
diff3
私たちが実行している場合strace -f
:
$ strace -qqfe execve -e signal=none diff3 a b c
execve("/usr/bin/diff3", ["diff3", "a", "b", "c"], 0x7ffef2bb2d78 /* 53 vars */) = 0
[pid 13360] execve("/usr/bin/diff", ["diff", "--horizon-lines=100", "--", "b", "c"], 0x7ffc019c6d50 /* 53 vars */) = 0
[pid 13361] execve("/usr/bin/diff", ["diff", "--horizon-lines=100", "--", "a", "c"], 0x7ffc019c6d50 /* 53 vars */) = 0
ご覧のとおり、2回呼び出さdiff3
れ、3diff
番目のファイルは両方の呼び出しのオペランドの1つです。
ksh<(...)
スタイルのプロセス置換の場合、ファイルはパイプです。
cmd1 <(cmd2)
同じです:
cmd2 | cmd1 /dev/fd/0
ゼロ以外のfdを使用することを除いて。
したがって、3番目の引数の場合、diff3
最初の引数は完全なdiff
入力を消費し、2番目の引数は読み取ることができないため、ファイルが空であるように見えます。
したがって、少なくとも3番目のパラメータはパイプにすることはできません。
使用している場合は、パイプの代わりに一時ファイルを使用するプロセス代替形式をzsh
使用できます。=(...)
diff3 <(cmd1) <(cmd2) =(cmd3)
(最初の2つはまだパイプかもしれません)。
あなたの場合:
$ diff3 \
<(grep -Po '\[\[.*?\]\]' intro.tex | sort) \
<(grep -Po '\[\[.*?\]\]' intro.tex | sort -u) \
=(sed -n 's/\\pnum %% \[\[/[[/p' intro.txt | sort)
(重複も削除し、grep
オプションを非オプションの前にuniq
移動しました。)-o
以下を使用して因数分解することもできます。
(){ diff3 $1 <(uniq<$1) $2; } =(grep -Po '\[\[.*?\]\]' intro.tex) \
=(sed -n 's/\\pnum %% \[\[/[[/p' intro.txt | sort)
1 3番目の引数がstdinを読み取ると-
解釈されると、diff3
2番目の引数はパイプになりません。diff
この場合、両方の呼び出しにパイプが渡されるためです。このマニュアルには次の内容が記載されています。」たくさんあるべきこれら3つのファイル名の1つは、標準入力にそのファイルを読み取るように指示すること-
です。diff3
」