끝에 새 줄이 있거나 없을 수있는 현재 디렉토리의 하위 디렉토리에 파일이 있습니다. 마지막에 줄 바꿈이없는 파일을 어떻게 찾을 수 있습니까?
나는 이것을 시도했다 :
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
.
답변
명확히하기 위해 LF (일명 \n
또는 줄 바꿈) 문자는 줄 구분 기호 이며 줄 구분 기호 가 아닙니다. 줄 바꿈 문자로 끝나지 않으면 줄이 끝나지 않습니다. a\nb
마지막 행 다음에 문자가 포함되어 있기 때문에 포함 된 파일 만 유효한 텍스트 파일이 아닙니다. 가 포함 된 파일에 대해서도 동일합니다 a
. 포함 된 파일에는 a\n
비어 있지 않은 줄이 하나 있습니다 .
따라서 하나 이상의 빈 줄로 끝나는 파일은 두 개의 줄 바꿈 문자로 끝나거나 단일 줄 바꿈 문자를 포함합니다.
만약:
tail -c 2 file | od -An -vtc
\n
또는을 출력 \n \n
하면 파일에 하나 이상의 후행 빈 줄이 포함됩니다. 아무것도 출력하지 않으면 빈 파일이고 출력하면 <anything-but-\0> \n
비어 있지 않은 줄로 끝납니다. 다른 것은 텍스트 파일이 아닙니다.
이제 그것을 사용하여 빈 줄로 끝나는 파일을 찾으려면 파일의 마지막 2 바이트 만 읽으므로 효율적으로 (특히 큰 파일의 경우) 효율적이지만 먼저 출력을 프로그래밍 방식으로 쉽게 파싱 할 수 없습니다. 하나의 구현 od
에서 다음 구현으로 일관성이 없으므로 파일 당 tail
하나씩 실행해야 od
합니다.
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
}
답변
with gnu sed
와 같은 쉘 zsh
(또는 bash
with shopt -s globstar
) :
sed -ns '${/./F}' ./**/*.styl
각 파일의 마지막 줄이 비어 있지 않은지 확인하여 파일 이름을 인쇄합니다.
당신이 반대를 원한다면 바로 교체 (마지막 줄이 비어있는 경우 파일 이름을 인쇄) /./
와/^$/
답변
마지막 줄이 비어있는 올바르게 종료 된 텍스트 파일은 2로 끝납니다 \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
.
답변
for file in *; do
# Check if the file is readable to avoid clutter
if cat "./$file" 2&>1 /dev/null; then
# Compare the last character with a single newline character.
if [ -n "$(tail -c 1 -- "./$file")" ]; then
echo "$file"
fi
# Also report empty files.
if [ $(wc -c < "./$file") -eq 0 ]; then
echo "$file"
fi
fi
done