어떤 경우에는 파일에 새 줄을 추가하려고 할 때 실제로 추가한 새 줄이 마지막 줄 끝에 삽입되는 것을 볼 수 있습니다.
예를 들어, 추가하기 전의 파일은 다음과 같습니다.
more /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
이제 다음을 추가합니다.
echo "182.2.3.4 host_1" >>/etc/hosts
우리는 다음을 얻었습니다:
more /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6182.2.3.4 host_1
아마도 가장 간단한 해결책은 다음과 같습니다.
echo >> /etc/hosts
하지만 다른 솔루션을 얻게 되어 기쁩니다.
답변1
이는 원본 파일의 마지막 줄 끝에 개행 문자가 없기 때문입니다. echo "182.2.3.4 host_1"
는 처음에 하나를 추가하지 않지만(그러나 뒤에 끝에 하나를 추가함 ...host_1
) 결과 파일은 추가하지 않습니다.
이 문제 때문에, 엄밀히 말하면,표준에서는 개행 문자로 끝나려면 "줄"이 필요합니다., 항상 해당 위치에 두어야 합니다. 일부 유틸리티는 마지막 줄 바꿈 없이 예상치 못한 동작을 일으킬 수 있습니다(예: wc -l
줄 바꿈을 계산하여 해당 줄을 한 줄로 계산하지 않음, read
줄 바꿈이 표시되지 않으면 오류 상태를 반환하는 내장 함수). 일부 편집자는 항상 추가하지만 일부 편집자는 그렇지 않습니다. 그렇지 않은 경우 마지막 줄 다음에 Enter를 누르거나 커서를 그 아래의 "빈 줄"로 이동하여 줄바꿈이 있는지 확인하세요.
유사한 파일은 다음을 사용하여 복구할 수 있습니다.
perl -i -pe '$_ .= "\n" unless /\n$/' file-maybe-without-nl.txt
후행 개행 문자가 이미 존재하는 경우 그대로 두어야 합니다. ( awk 1 < file.txt > fixed.txt
또한 작동하는 것 같지만 awk에는 표준 내부 편집 기능이 없습니다. sed
있지만 사용 방법을 모르겠습니다.)
물론, echo >> /etc/hosts
, 처럼 무조건 줄바꿈을 추가할 수도 있지만 echo -e '\n182.2.3.4 host_1' >> /etc/hosts
, 파일을 추가하기 전에 형식이 잘 되어 있으면 중간에 가짜 빈 줄이 추가됩니다.
전체 줄을 읽지 않고도 최종 개행 문자를 확인하는 한 가지 방법은 마지막 줄(또는 줄 조각) 또는 마지막 문자만 사용하거나 가져오는 것 tail -n1
입니다 . tail -c1
그 다음에
[ "$(tail -c1 "$f")" = "" ] || echo >> "$f"
필요한 경우 추가하여 사용할 수 있습니다. (이것은 개행 문자를 먹는 명령 대체에 의존하므로 개행 문자가 있으면 확장은 비어 있습니다.예) 또는 다음을 사용합니다 read
(개행 문자가 표시되지 않으면 오류 상태를 반환합니다).
tail -c1 file | read -r tmp || echo >> file
tail
(후자의 명령 과 전체 명령에 대한 아이디어 는 다음 블로그 게시물에서 차용했습니다.https://backreference.org/2010/05/23/sanitizing-files-with-no-trailing-newline/)
CR(캐리지 리턴) 문자는 Unix 계열 시스템에서 줄 종결자로 사용되는 줄 바꿈/LF(줄 바꿈) 문자와 다릅니다. (CR+LF는 DOS 및 Windows에서 줄 종결자로 사용됩니다.)