쉘에서 NULL 문자를 처리하는 이식 가능한 방법이 있습니까?
일반적인 예는 쉘(및 쉘만)의 출력을 find ... -print0
파이프 또는 명령 대체 결과로 분할하는 것입니다. 예를 들어 휴대용이란 이상적으로는 껍질이 강력하지 않거나 막히지 않는 것을 의미 bash
합니다 zsh
. "네이키드 POSIX 쉘"(모든 POSIX 버전)에서 이것이 가능합니까?
답변1
null
POSIX는 텍스트 포함 문자를 처리하기 위한 표준 유틸리티를 고려하지 않습니다 . -print0
사용하는 옵션 자체 find
는 의 GNU
영향을 받지 않습니다 POSIX
.
null
s가 포함된 데이터 스트림을 처리하기 위해 쉘 스크립트를 사용하는 한 가지 방법 POSIX
은 먼저 이를 실제 텍스트로 변환 od
하고 해당 텍스트를 처리하는 것입니다.
어쨌든, 가 있다면 애초에 그러한 제한이 없는 GNU find
다른 유틸리티가 있을 것입니다 .GNU
답변2
Bash는 read
'의 옵션을 사용하여 -d
이를 처리 할 수 있습니다.
find . -print0 | while read -r -d '' line; do
# something with $line
done
그러나 이것이 POSIX인지는 알 수 없습니다.
답변3
뒤쪽에비슷한 질문 찾기, 이것은 제가 잠시 후에 알아낸 것입니다... 이것이 POSIX 쉘에서 가능한지 확실하지 않습니다. Cygwin에서 이것을 시도했습니다. 단지 재미를 위해 null 문자를 사용하여 문제를 해결했습니다.
문제가 다음과 같다고 상상해 보십시오. 널 문자가 포함된 (일부) 파일이 있습니다. 이러한 파일이 무엇인지, 어디에 있는지 정확히 알 수 없습니다. 당신의 임무는 가능한 모든 파일에서 널 문자를 제거하는 것입니다.
아래에서 첫 번째 명령은 null 문자가 포함된 행을 표시하고, 다른 명령은 null 문자를 줄 바꿈으로 변환합니다(마지막 명령은 임시 파일을 삭제합니다).
find . ! -type d -exec perl -ne '/\000/ and print;' {} \; > /tmp/null-lines
tr -s '\000' '\n' < /tmp/null-lines > with-null-lines.txt
rm /tmp/null-lines
그런 다음 결과 줄의 각 줄을 읽고 해당 줄이 어떤 파일에 속하는지 찾아야 합니다. 이를 위해 먼저 확인해야 할 모든 파일을 저장한 다음 일치하는 줄이 있는지 확인합니다.
find . ! -type d -print > files.txt
while read line; do while read line2; do if grep -q "$line2" "$line"; then echo "$line" >> examination.txt; fi; done < with-null-lines.txt; done < files.txt
(루프를 다시 실행하기 전에 "examination.txt" 파일을 삭제하세요)
이제 발생 횟수를 세어보고 발생 횟수가 1을 초과하면 null 문자가 여러 개일 가능성이 높습니다(물론 하나만 있으면 찾기가 더 어려워집니다).
uniq -c examination.txt | grep -v "1"
여기에는 널 문자가 포함된 (대부분의) 파일이 나열되어야 합니다. "with-null-lines.txt" 줄을 무시하세요. 또한 파일에 동일한 텍스트가 있는 경우 목록에서 수동으로 지워야 하는 일부 무고한 파일이 표시될 수도 있습니다.
널 문자가 개행 문자 위치에 없으면 그냥 제거하십시오.
uniq -d examination.txt > files-to-clean.txt while read line; do ex -s +"%s/\%x00//g" -cwq $line; done < files-to-clean.txt
또는
tr
파일의 경우 ,를 사용하세요.tr -d '\000' < inputfile > outputfile
널 문자가 있는 파일을 지우려면(모두 개행 위치에 있다고 가정) 다음 명령을 사용하십시오.
tr -s '\000' '\n' < inputfile > outputfile
tr
한 번에 여러 파일을 처리하는 방법을 너무 많이 조사하지 않고.