프로세스 대체 입력의 diff3은 차이점을 찾지만 파일의 동일한 데이터에 대한 diff3은 차이점을 찾지 못하는 이유는 무엇입니까?

프로세스 대체 입력의 diff3은 차이점을 찾지만 파일의 동일한 데이터에 대한 diff3은 차이점을 찾지 못하는 이유는 무엇입니까?

파일의 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

보시다시피 두 번 diff3호출되고 diff세 번째 파일은 두 호출의 피연산자 중 하나입니다.

ksh 스타일 <(...)프로세스 교체의 경우 파일은 파이프입니다.

cmd1 <(cmd2)

동일합니다:

cmd2 | cmd1 /dev/fd/0

0이 아닌 fd를 사용하는 것을 제외하고.

따라서 세 번째 인수의 경우 diff3첫 번째 인수는 diff전체 입력을 소비하고 두 번째 인수는 읽을 내용이 없으므로 파일이 비어 있는 것으로 나타납니다.

따라서 적어도 세 번째 매개변수는 파이프가 될 수 없습니다.

사용하는 경우 파이프 대신 임시 파일을 사용하는 프로세스 대체 형식을 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 세 번째 인수가 stdin을 읽는 것으로 -해석 되면 diff3두 번째 인수는 파이프가 될 수 없습니다. diff이 경우 두 호출 모두에 파이프가 전달되기 때문입니다. 설명서에 다음과 같은 내용이 나와 있습니다."많아야 하나이 세 가지 파일 이름 중 하나 는 표준 입력에 해당 파일을 읽도록 -지시하는 입니다. diff3"

관련 정보