![NULL로 끝나는 레코드에 comm 사용](https://linux55.com/image/134393/NULL%EB%A1%9C%20%EB%81%9D%EB%82%98%EB%8A%94%20%EB%A0%88%EC%BD%94%EB%93%9C%EC%97%90%20comm%20%EC%82%AC%EC%9A%A9.png)
다음으로 끝남답변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에서는 ① ② ③의 상대적 순서가 수정되었지만 다음을 사용할 수 있습니다.