
오버 인답변list2
다른 질문으로, 나는 다음과 같은 구조를 사용하여 에 나타나지 않는 파일을 찾고 싶었습니다 list1
.
( cd dir1 && find . -type f -print0 ) | sort -z > list1
( cd dir2 && find . -type f -print0 ) | sort -z > list2
comm -13 list1 list2
그러나 내 버전에서는 NULL로 끝나는 레코드를 처리할 수 없기 때문에 난관에 부딪혔습니다 comm
. (일부 배경 정보: 계산된 목록을 에 전달하므로 rm
특히 새 줄이 포함될 수 있는 파일 이름을 처리할 수 있기를 원합니다.)
쉬운 예제를 원한다면 이것을 시도하십시오
mkdir dir1 dir2
touch dir1/{a,b,c} dir2/{a,c,d}
( cd dir1 && find . -type f ) | sort > list1
( cd dir2 && find . -type f ) | sort > list2
comm -13 list1 list2
NULL로 끝나는 줄이 없으면 여기서 출력은 ./d
에서만 나타나는 단일 요소입니다 list2
.
find ... -print0 | sort -z
목록을 생성하는 데 사용할 수 있기를 바랍니다 .
에는 나타나지만 comm
NULL로 종료되는 레코드를 출력하는 것과 동일한 것을 가장 잘 다시 구현할 수 있는 방법은 무엇입니까 ?list2
list1
답변1
GNU comm
(GNU coreutils 8.25 기준)에는 이제 이에 대한 -z
/ 옵션이 있습니다.--zero-terminated
이전 버전의 GNU에서는 comm
NUL과 NL을 교체할 수 있어야 합니다.
comm -13 <(cd dir1 && find . -type f -print0 | tr '\n\0' '\0\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n\0' '\0\n' | sort) |
tr '\n\0' '\0\n'
이 방법은 comm
줄 바꿈으로 구분된 레코드에서도 작동하지만 NUL로 인코딩된 입력의 실제 줄 바꿈을 사용하므로 줄 바꿈이 포함된 파일 이름으로 여전히 안전합니다.
C
GNU 시스템과 대부분의 UTF-8 로케일에는 동일하게 정렬되어 여기서 문제를 일으킬 수 있는 다른 문자열이 있기 때문에 로케일을 다음으로 설정할 수도 있습니다 .
이는 매우 일반적인 트릭입니다(참조:일치하는 라인 반전, NUL로 구분) 의 또 다른 예는 comm
입력에 NUL을 지원하는 유틸리티가 필요하며 GNU 시스템 외부에서는 상대적으로 드뭅니다.
¹ 예:
$ touch dir1/{①,②} dir2/{②,③}
$ comm -12 <(cd dir1 && find . -type f -print0 | tr '\n\0' '\0\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n\0' '\0\n' | sort)
./③
./②
$ (export LC_ALL=C
comm -12 <(cd dir1 && find . -type f -print0 | tr '\n\0' '\0\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n\0' '\0\n' | sort))
./②
(2019년 편집: 최신 버전의 GNU libc에서는 ① ② ③의 상대적 순서가 수정되었지만 다음을 사용할 수 있습니다.