쉘에서 NULL 문자 처리

쉘에서 NULL 문자 처리

쉘에서 NULL 문자를 처리하는 이식 가능한 방법이 있습니까?

일반적인 예는 쉘(및 쉘만)의 출력을 find ... -print0파이프 또는 명령 대체 결과로 분할하는 것입니다. 예를 들어 휴대용이란 이상적으로는 껍질이 강력하지 않거나 막히지 않는 것을 의미 bash합니다 zsh. "네이키드 POSIX 쉘"(모든 POSIX 버전)에서 이것이 가능합니까?

답변1

nullPOSIX는 텍스트 포함 문자를 처리하기 위한 표준 유틸리티를 고려하지 않습니다 . -print0사용하는 옵션 자체 find는 의 GNU영향을 받지 않습니다 POSIX.

nulls가 포함된 데이터 스트림을 처리하기 위해 쉘 스크립트를 사용하는 한 가지 방법 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" 줄을 무시하세요. 또한 파일에 동일한 텍스트가 있는 경우 목록에서 수동으로 지워야 하는 일부 무고한 파일이 표시될 수도 있습니다.

  1. 널 문자가 개행 문자 위치에 없으면 그냥 제거하십시오.

    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
    
  2. 널 문자가 있는 파일을 지우려면(모두 개행 위치에 있다고 가정) 다음 명령을 사용하십시오.

    tr -s '\000' '\n' < inputfile > outputfile
    

    tr한 번에 여러 파일을 처리하는 방법을 너무 많이 조사하지 않고.

관련 정보