버전 제어 시스템을 사용하면 diff가 말할 때 소음에 짜증이납니다 No newline at end of file
.
그래서 궁금해했습니다. 파일 끝에 줄 바꿈을 추가하여 해당 메시지를 제거하는 방법은 무엇입니까?
답변
프로젝트를 재귀 적으로 소독하려면이 oneliner를 사용하십시오.
git ls-files -z | while IFS= read -rd '' f; do tail -c1 < "$f" | read -r _ || echo >> "$f"; done
설명:
-
git ls-files -z
저장소에 파일을 나열합니다. 작업을 특정 파일 / 디렉토리로 제한하려는 경우에 유용한 추가 매개 변수로 선택적 패턴을 사용합니다. 다른 방법으로,find -print0 ...
또는 유사한 프로그램을 사용 하여 영향을받는 파일을 나열 할 수 있습니다. 파일이NUL
구분 된 항목 인지 확인하십시오 . -
while IFS= read -rd '' f; do ... done
공백 및 / 또는 줄 바꿈이 포함 된 파일 이름을 안전하게 처리하여 항목을 반복합니다. -
tail -c1 < "$f"
파일에서 마지막 문자를 읽습니다. -
read -r _
후행 줄 바꿈이 없으면 0이 아닌 종료 상태로 종료합니다. -
|| echo >> "$f"
이전 명령의 종료 상태가 0이 아닌 경우 파일에 개행을 추가합니다.
답변
여기 있습니다 :
sed -i -e '$a\' file
대안으로 OS X의 경우 sed
:
sed -i '' -e '$a\' file
이렇게 하면 줄 바꿈으로 끝나지 않은 경우 에만\n
파일 끝에 추가 됩니다 . 따라서 두 번 실행하면 다른 줄 바꿈이 추가되지 않습니다.
$ cd "$(mktemp -d)"
$ printf foo > test.txt
$ sed -e '$a\' test.txt > test-with-eol.txt
$ diff test*
1c1
< foo
\ No newline at end of file
---
> foo
$ echo $?
1
$ sed -e '$a\' test-with-eol.txt > test-still-with-one-eol.txt
$ diff test-with-eol.txt test-still-with-one-eol.txt
$ echo $?
0
답변
보세요 :
$ echo -n foo > foo
$ cat foo
foo$
$ echo "" >> foo
$ cat foo
foo
그래서 echo "" >> noeol-file
트릭을 할해야합니다. (또는 이러한 파일을 식별 하고 수정하도록 요청 했습니까?)
edit 에서 ""
from을 제거했습니다 echo "" >> foo
(@yuyichao의 의견 참조) edit2 가 ""
다시 추가 했습니다 ( 그러나 @Keith
Thompson의 의견 참조)
답변
를 사용하는 다른 솔루션 ed
. 이 솔루션은 마지막 줄에만 영향을 미칩니다 \n
.
ed -s file <<< w
그것은 본질적으로 스크립트를 통해 편집하기 위해 파일을 여는 작업이며, 스크립트는 w
파일을 디스크에 다시 쓰는 단일 명령입니다. ed(1)
맨 페이지 에있는이 문장에 근거 합니다 :
한계 (...) 텍스트 (이진이 아닌) 파일이 줄 바꿈 문자로 끝나지 않으면 그런 다음 ed는 읽거나 쓸 때 하나를 추가합니다. 이진의 경우 ed는 읽기 / 쓰기에 개행을 추가하지 않습니다.
답변
결석 한 최종 개행을 텍스트 파일에 추가하는 간단하고 이식 가능한 POSIX 호환 방법은 다음과 같습니다.
[ -n "$(tail -c1 file)" ] && echo >> file
이 방법은 전체 파일을 읽을 필요는 없습니다. 그것은 단순히 EOF를 추구하고 거기서부터 일할 수 있습니다.
이 방법은 또한 임시 파일 (예 : sed -i)을 만들 필요가 없으므로 하드 링크에는 영향을 미치지 않습니다.
echo는 명령 대체 결과가 비어 있지 않은 문자열 인 경우에만 파일에 개행을 추가합니다. 파일이 비어 있지 않고 마지막 바이트가 줄 바꿈이 아닌 경우에만 발생할 수 있습니다.
파일의 마지막 바이트가 줄 바꿈이면 tail은 해당 파일을 반환 한 다음 명령 대체에서 제거합니다. 결과는 빈 문자열입니다. -n 테스트가 실패하고 에코가 실행되지 않습니다.
파일이 비어 있으면 명령 대체 결과도 빈 문자열이며 echo가 다시 실행되지 않습니다. 빈 파일은 유효하지 않은 텍스트 파일이 아니거나 빈 줄이있는 비어 있지 않은 텍스트 파일과 동일하지 않기 때문에 바람직합니다.
답변
다음에 관계없이 줄 바꿈을 추가하십시오.
echo >> filename
다음은 파이썬을 사용하여 줄 바꿈을 추가하기 전에 줄 바꿈이 있는지 확인하는 방법입니다.
f=filename; python -c "import sys; sys.exit(open(\"$f\").read().endswith('\n'))" && echo >> $f
답변
가장 빠른 해결책은 다음과 같습니다.
[ -n "$(tail -c1 file)" ] && printf '\n' >>file
-
정말 빠릅니다.
중간 크기의 파일seq 99999999 >file
에서는 몇 초가 걸립니다.
다른 솔루션은 시간이 오래 걸립니다 :[ -n "$(tail -c1 file)" ] && printf '\n' >>file 0.013 sec vi -ecwq file 2.544 sec paste file 1<> file 31.943 sec ed -s file <<< w 1m 4.422 sec sed -i -e '$a\' file 3m 20.931 sec
-
ash, bash, lksh, mksh, ksh93, attsh 및 zsh에서 작동하지만 yash에서는 작동하지 않습니다.
- 개행을 추가 할 필요가 없으면 파일 타임 스탬프를 변경하지 않습니다.
여기에 제시된 다른 모든 솔루션은 파일의 타임 스탬프를 변경합니다. - 위의 모든 솔루션은 유효한 POSIX입니다.
yash (및 위에 나열된 다른 모든 셸)에 이식 가능한 솔루션이 필요한 경우 조금 더 복잡해질 수 있습니다.
f=file
if [ "$(tail -c1 "$f"; echo x)" != "$(printf '\nx')" ]
then printf '\n' >>"$f"
fi