끝에 빈 줄이 없는 파일을 찾는 방법은 무엇입니까?

끝에 빈 줄이 없는 파일을 찾는 방법은 무엇입니까?

현재 디렉터리의 하위 디렉터리에 끝에 개행 문자가 있을 수도 있고 없을 수도 있는 파일이 있습니다. 끝에 개행 문자가 없는 파일을 어떻게 찾을 수 있나요?

나는 이것을 시도했습니다 :

find . -name '*.styl' | while read file; do
    awk 'END{print}' $file | grep -E '^$' > /dev/null || echo $file;
done

하지만 작동하지 않습니다. awk 'END{print}' $file와 동일하게 빈 새 줄 앞에 줄을 인쇄합니다 tail -n 1 $file.

답변1

명확히 하기 위해 LF(일명 \n개행 문자) 문자는 다음 줄입니다.구분 기호, 이는 줄 구분 기호가 아닙니다. 개행 문자로 끝나지 않는 한 줄은 끝나지 않습니다. 포함된 파일은 a\nb마지막 줄 뒤에 문자가 포함되어 있으므로 유효한 텍스트 파일이 아닙니다. 비어 있지 않은 줄이 하나만 포함된 파일의 경우 a.a\n

따라서 하나 이상의 빈 줄로 끝나는 파일은 두 개의 줄 바꿈으로 끝나거나 하나의 줄 바꿈을 포함합니다.

만약에:

 tail -c 2 file | od -An -vtc

출력 \n또는 \n \n파일에는 적어도 하나의 후행 빈 줄이 포함되어 있습니다. 아무것도 출력하지 않으면 빈 파일이고, 출력하면 <anything-but-\0> \n비어 있지 않은 줄로 끝납니다. 그 외에는 텍스트 파일이 아닙니다.

이제 이것을 사용하여 빈 줄로 끝나는 파일을 찾으려면 파일의 마지막 2바이트만 읽기 때문에 작동합니다(특히 대용량 파일의 경우). 그러나 먼저 출력을 프로그래밍 방식으로 구문 분석하기가 쉽지 않습니다. 한 구현에서 다음 구현까지 일관성이 없으므로 각 파일에 대해 하나씩 od실행해야 합니다 .tailod

find . -type f -size +0 -exec gawk '
  ENDFILE{if ($0 == "") print FILENAME}' {} +

(빈 줄로 끝나는 파일 찾기)는 가능한 한 적은 수의 명령을 실행하지만 이는 모든 파일의 전체 내용을 읽는다는 의미입니다.

이상적으로는 자체적으로 파일의 끝을 읽을 수 있는 셸이 필요합니다.

그리고 zsh:

zmodload zsh/system
for f (**/*(D.L+0)) {
  {
    sysseek -w end -2
    sysread
    [[ $REPLY = $'\n' || $REPLY = $'\n\n' ]] && print -r -- $f
  } < $f
}

답변2

gnu sed및 유사한 쉘을 사용하십시오 zsh(또는 bash사용 shopt -s globstar):

sed -ns '${/./F}' ./**/*.styl

각 파일의 마지막 줄이 비어 있지 않은지 확인하고 비어 있으면 파일 이름을 인쇄합니다.
반대 결과를 원한다면 (마지막 줄이 비어 있으면 파일 이름을 인쇄하십시오) 다음 /./으로 바꾸십시오./^$/

답변3

적절하게 종료된 텍스트 파일은 빈 마지막 줄로 끝나고 두 개의 \n.

그렇다면 우리의 기대값 tail -c2은 와 같아야 합니다 $'\n\n'.

불행히도 명령 확장은 후행 새 줄을 제거합니다. 몇 가지 조정이 필요합니다.

f=filename
nl='
'
t=$(tail -c2 $f; printf x)  # capture the last two characters.
r="${nl}${nl}$"                 # regex for: "ends in two newlines".
[[ ${t%x} =~ $r ]] &&  echo "file $f ends in an empty line"

어떤 파일에 줄바꿈 문자가 없는지 확인하기 위해 약간 확장할 수도 있습니다.

nl='
'
nl=$'\n'
find . -type f -name '*.styl' | while read f; do
    t=$(tail -c2 $f; printf x); r1="${nl}$"; r2="${nl}${r1}"
    [[ ${t%x} =~ $r1 ]] || echo "file $f is missing a trailing newline"
    [[ ${t%x} =~ $r2 ]] && echo "$f"
done

$'\r\n필요한 경우 줄 바꿈을 이와 같이 변경할 수 있습니다.
이 경우에도 tail -c2로 변경합니다 tail -c4.

관련 정보