파일 끝에 줄 바꿈을 추가하는 방법은 무엇입니까? 말할 때 소음에 짜증이납니다 No

버전 제어 시스템을 사용하면 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 

  1. 정말 빠릅니다.
    중간 크기의 파일 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
  2. ash, bash, lksh, mksh, ksh93, attsh 및 zsh에서 작동하지만 yash에서는 작동하지 않습니다.

  3. 개행을 추가 할 필요가 없으면 파일 타임 스탬프를 변경하지 않습니다.
    여기에 제시된 다른 모든 솔루션은 파일의 타임 스탬프를 변경합니다.
  4. 위의 모든 솔루션은 유효한 POSIX입니다.

yash (및 위에 나열된 다른 모든 셸)에 이식 가능한 솔루션이 필요한 경우 조금 더 복잡해질 수 있습니다.

f=file
if       [ "$(tail -c1 "$f"; echo x)" != "$(printf '\nx')" ]
then     printf '\n' >>"$f"
fi