[file] 텍스트 파일이 줄 바꿈으로 끝나야하는 이유는 무엇입니까?
나는 여기의 모든 사람들이 모든 텍스트 파일이 줄 바꿈으로 끝나야한다는 속담에 익숙하다고 가정합니다. 나는이 “규칙”을 몇 년 동안 알고 있었지만 항상 궁금했습니다. 왜 그렇습니까?
답변
그것이 POSIX 표준이 라인을 정의하는 방식 이기 때문에 :
- 3.206 라인
- 0 개 이상의 비 <newline> 문자와 종료 <newline> 문자 순서.
따라서 개행 문자로 끝나지 않는 행은 실제 행으로 간주되지 않습니다. 따라서 일부 프로그램은 줄 바꿈이 종료되지 않은 경우 파일의 마지막 줄을 처리하는 데 문제가 있습니다.
터미널 에뮬레이터에서 작업 할 때이 지침에 적어도 하나의 장점이 있습니다. 모든 Unix 도구는이 규칙을 기대하고 함께 사용합니다. 예를 들어로 파일을 연결할 때 cat
줄 바꿈으로 끝나는 파일은 다음이없는 파일과 다른 효과를 갖습니다.
$ more a.txt
foo
$ more b.txt
bar$ more c.txt
baz
$ cat {a,b,c}.txt
foo
barbaz
그리고 이전 예제에서도 보여 주듯이, 명령 줄에 파일을 표시 할 때 (예 :를 통해 more
) 줄 바꿈으로 끝나는 파일이 올바르게 표시됩니다. 잘못 종료 된 파일이 깨졌을 수 있습니다 (두 번째 줄).
일관성을 유지하려면이 규칙을 따르는 것이 매우 유용합니다. 그렇지 않으면 기본 Unix 도구를 다룰 때 추가 작업이 필요합니다.
다르게 생각하십시오 : 줄 바꿈으로 줄이 끝나지 않으면 cat
유용한 명령을 만드는 것이 훨씬 어렵습니다. 파일을 연결하는 명령을 만드는 방법
- 그것은 각 파일의 시작을 새로운 줄에 넣습니다. 그것은 당신이 원하는 시간의 95 %입니다; 그러나
- 위의 예제에서
b.txt
와c.txt
? 사이에서 두 파일의 마지막 줄과 첫 줄을 병합 할 수 있습니다 .
물론이는 풀 수 있지만의 사용 확인해야합니다 cat
(위치 명령 행 인수, 예를 추가하여 더 복잡한을 cat a.txt --no-newline b.txt c.txt
지금), 및 명령 보다는 다른 파일과 함께 붙여 넣기하는 방법을 각 개별 파일을 제어합니다. 이것은 거의 확실하지 않습니다.
… 또는 종료하지 않고 계속되는 줄을 표시하려면 특수한 센티넬 문자를 도입해야합니다. 글쎄, 이제 당신은 역행을 제외하고 POSIX와 같은 상황에 갇혀 있습니다 (행 종료 문자가 아닌 행 연속 문자).
자, 비 POSIX 호환 시스템 (요즘의 대부분의 Windows 것을), 요점은 논쟁은 다음과 같습니다 파일은 일반적으로 줄 바꿈으로 끝나지 않고, 예를 들어 줄 힘의 (비공식) 정의는 “있는 텍스트 여야 분리 줄 바꿈에 의해” (강조 표시). 이것은 전적으로 유효합니다. 그러나 구조화 된 데이터 (예 : 프로그래밍 코드)의 경우 구문 분석이 최소로 복잡해집니다. 일반적으로 구문 분석기를 다시 작성해야합니다. 파서가 원래 POSIX 정의를 염두에두고 작성된 경우 파서보다는 토큰 스트림을 수정하는 것이 더 쉬울 수 있습니다. 즉, 입력의 끝에 “인공 줄 바꿈”토큰을 추가하십시오.
답변
각 줄은 마지막 줄을 포함하여 줄 바꿈 문자로 끝나야합니다. 줄 바꿈이 끝나지 않은 파일의 마지막 줄을 처리하는 데 문제가있는 프로그램이 있습니다.
GCC는 파일을 처리 할 수 없기 때문에 가 아니라 표준의 일부로 해야 하기 때문에 경고 합니다.
C 언어 표준에 따르면 비어 있지 않은 소스 파일은 줄 바꿈 문자로 끝나고 백 슬래시 문자 바로 앞에 오지 않아야합니다.
이것은 “shall”절이므로이 규칙을 위반하면 진단 메시지를 보내야합니다.
이것은 ANSI C 1989 표준의 2.1.1.2 섹션에 있습니다. ISO C 1999 표준 (그리고 아마도 ISO C 1990 표준)의 5.1.1.2 절.
참조 : GCC / GNU 메일 아카이브 .
답변
이 답변은 의견이 아닌 기술적 답변을 시도한 것입니다.
POSIX 순수 주의자가 되려면 다음과 같이 라인을 정의하십시오.
0 개 이상의 비 <newline> 문자와 종료 <newline> 문자 순서.
출처: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206
불완전한 라인 :
파일 끝에서 하나 이상의 비 <newline> 문자 시퀀스.
출처: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_195
다음과 같은 텍스트 파일 :
0 개 이상의 줄로 구성된 문자가 포함 된 파일입니다. 행은 NUL 문자를 포함하지 않으며 <newline> 문자를 포함하여 길이가 {LINE_MAX} 바이트를 초과 할 수 없습니다. POSIX.1-2008은 텍스트 파일과 이진 파일을 구분하지 않지만 (ISO C 표준 참조) 많은 유틸리티는 텍스트 파일에서 작업 할 때 예측 가능하거나 의미있는 출력 만 생성합니다. 이러한 제한이있는 표준 유틸리티는 항상 STDIN 또는 INPUT FILES 섹션에 “텍스트 파일”을 지정합니다.
출처: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_397
다음과 같은 문자열 :
첫 번째 null 바이트로 끝나고 포함 된 연속적인 바이트 시퀀스입니다.
출처: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_396
이로부터 우리는 잠재적으로 어떤 유형의 문제가 발생할 수 있는 유일한 시간 은 파일 의 줄 또는 파일 의 개념을 텍스트 파일 로서 텍스트 파일 ( 텍스트 파일 이 0으로 구성 되어 있다는 것)을 다룰 때 뿐이라는 것을 알 수 있습니다 또는 그 이상의 줄과 우리가 알고있는 줄은 <newline>으로 끝나야합니다).
적절한 사례 : wc -l filename
.
에서 wc
의 사용 설명서 우리는 읽기 :
줄은 <newline> 문자로 구분 된 문자열로 정의됩니다.
JavaScript, HTML 및 CSS 파일이 텍스트 파일 이라는 의미는 무엇입니까 ?
브라우저, 최신 IDE 및 기타 프런트 엔드 응용 프로그램에서는 EOF에서 EOL을 건너 뛰는 데 문제가 없습니다. 응용 프로그램은 파일을 올바르게 구문 분석합니다. 모든 운영 체제가 POSIX 표준을 준수하는 것은 아니므로, OS 이외의 도구 (예 : 브라우저)가 POSIX 표준 (또는 OS 레벨 표준)에 따라 파일을 처리하는 것은 비현실적입니다.
결과적으로 EOF의 EOL이 UNIX OS에서 실행되는지 여부에 관계없이 EOF의 EOL이 애플리케이션 레벨에서 사실상 부정적인 영향을 미치지 않을 것이라고 확신 할 수 있습니다.
이 시점에서 클라이언트 측에서 JS, HTML, CSS를 다룰 때 EOF에서 EOL을 건너 뛰는 것이 안전하다고 확신 할 수 있습니다. 실제로 <newline>을 포함하지 않는 이러한 파일 중 하나를 축소하는 것이 안전하다고 말할 수 있습니다.
이 단계를 한 단계 더 나아가서 NodeJS에 관한 한 POSIX 표준을 준수 할 수 없다는 점은 POSIX를 준수하지 않는 환경에서 실행할 수 있다는 것입니다.
그때 우리는 무엇을 남겼습니까? 시스템 레벨 툴링.
이는 POSIX의 의미에 기능을 적용하기 위해 노력하는 도구 (예 :에 표시된대로 줄 정의)와 관련하여 발생할 수있는 유일한 문제입니다 wc
.
그럼에도 불구하고 모든 쉘이 POSIX를 자동으로 준수하지는 않습니다. 예를 들어 Bash는 기본적으로 POSIX 동작으로 설정되지 않습니다. 그것을 가능하게하는 스위치가 있습니다 : POSIXLY_CORRECT
.
EOL의 가치에 대한 생각은 <newline>입니다 : https://www.rfc-editor.org/old/EOLstory.txt
모든 실용적인 의도와 목적을 위해 툴링 트랙에 머물면서 다음을 고려하십시오.
EOL이없는 파일로 작업 해 봅시다. 이 글을 쓰는 시점에서이 예제의 파일은 EOL이없는 축소 된 JavaScript입니다.
curl http://cdnjs.cloudflare.com/ajax/libs/AniJS/0.5.0/anijs-min.js -o x.js
curl http://cdnjs.cloudflare.com/ajax/libs/AniJS/0.5.0/anijs-min.js -o y.js
$ cat x.js y.js > z.js
-rw-r--r-- 1 milanadamovsky 7905 Aug 14 23:17 x.js
-rw-r--r-- 1 milanadamovsky 7905 Aug 14 23:17 y.js
-rw-r--r-- 1 milanadamovsky 15810 Aug 14 23:18 z.js
통지 cat
파일 크기가 정확히 개별 부품의 합계입니다. JavaScript 파일의 연결이 JS 파일의 문제인 경우, 각 JavaScript 파일을 세미콜론으로 시작하는 것이 더 적절한 문제입니다.
이 스레드에서 다른 사람이 언급했듯이 cat
출력이 두 줄이 아닌 한 줄이되는 두 파일 을 원한다면 어떻게해야 합니까? 즉, cat
해야 할 일을합니다.
는 <newline>이 아니라 EOF까지 입력을 읽는 man
것에 cat
대해서만 언급합니다. 주의가 있는지 -n
의 스위치는 cat
또한 비 <개행> 종료 행 (또는 출력한다 불완전한 라인 A와) 라인 – 인을 카운트에서 시작하는 1 단계 (받는 항 man
).
-n 1부터 시작하여 출력 라인의 번호를 지정합니다.
POSIX가 어떻게 라인을 정의하는지 이해 했으므로 ,이 동작은 모호하거나 실제로 비 호환이됩니다.
주어진 도구의 목적과 규정을 이해하면 EOL로 파일을 종료하는 것이 얼마나 중요한지를 결정하는 데 도움이됩니다. C, C ++, Java (JARs) 등에서 일부 표준은 유효성에 대한 줄 바꿈을 지시합니다 .JS, HTML, CSS에 대한 표준은 없습니다.
예를 들어, wc -l filename
하나 를 사용하는 대신 할 수 awk '{x++}END{ print x}' filename
있고 작업의 성공이 우리가 작성하지 않은 처리하려는 파일 (예 : 축소 된 JS와 같은 타사 라이브러리)에 의해 위험에 처하지 않음을 확신 curl
하십시오. 의도는 진정으로 줄 을 세는 것이 었습니다 POSIX 호환 의미에서 .
결론
JS, HTML 및 CSS와 같은 특정 텍스트 파일에 대해 EOF에서 EOL을 건너 뛰는 것이 실제로 부정적인 영향을 미치는 실제 사용 사례는 거의 없습니다. <newline>을 사용하는 경우 툴링의 신뢰성을 우리가 작성하는 파일로만 제한하고 타사 파일에서 발생한 잠재적 오류까지 열 수 있습니다.
이야기의 교훈 : EOF에서 EOL에 의존하는 약점이없는 툴링 엔지니어.
EOL을 건너 뛰는 것이 어떻게 악영향을 미치는지 검토 할 수있는 사용 사례를 JS, HTML 및 CSS에 적용 할 때 자유롭게 게시하십시오.
답변
다음의 차이점 과 관련이있을 수 있습니다 .
- 텍스트 파일 (각 줄은 줄 끝으로 끝나야합니다)
- 이진 파일 (알아야 할 실제 “줄”이 없으며 파일 길이를 유지해야합니다)
각 줄이 줄 끝으로 끝나는 경우 예를 들어 두 개의 텍스트 파일을 연결하면 첫 번째 줄의 마지막 줄이 두 번째 줄의 첫 줄로 바뀌지 않습니다.
또한 편집기는 파일이 줄 끝으로 끝나는 지 여부를로드에서 확인하고 파일을 로컬 옵션 ‘eol’에 저장 한 후 파일을 쓸 때이를 사용할 수 있습니다.
몇 년 최종 EOL, “잊지”는 않았다 (2005) 많은 편집자 (ZDE, 이클립스, Scite를, …) 백업 매우 평가되지 않았습니다 .
뿐만 아니라 최종 EOL을 ‘새 줄 시작’으로 잘못 해석하고 실제로 다른 줄이 이미 존재하는 것처럼 표시하기 시작합니다.
위의 편집기 중 하나에서 파일을 여는 것과 비교할 때 vim과 같이 잘 작동하는 텍스트 편집기가있는 ‘적절한’텍스트 파일에서 매우 잘 보입니다. 파일의 실제 마지막 줄 아래에 여분의 줄이 표시되었습니다. 다음과 같은 것이 보입니다 :
1 first line
2 middle line
3 last line
4
답변
일부 도구는 이것을 기대합니다. 예를 들어 다음과 같이 wc
예상됩니다.
$ echo -n "Line not ending in a new line" | wc -l
0
$ echo "Line ending with a new line" | wc -l
1
답변
기본적으로 최종 EOL EOF를 얻지 못하면 파일을 올바르게 처리하지 못하는 많은 프로그램이 있습니다.
GCC는 C 표준의 일부로 예상되므로 이에 대해 경고합니다. (섹션 5.1.1.2)
답변
이것은 단순한 터미널이 사용 된 초기부터 시작되었습니다. 개행 문자는 전송 된 데이터의 ‘플러시’를 트리거하는 데 사용되었습니다.
오늘날 개행 문자는 더 이상 필요하지 않습니다. 물론 개행이 없으면 많은 앱에 여전히 문제가 있지만 해당 앱의 버그로 간주합니다.
그러나 줄 바꿈 이 필요한 텍스트 파일 형식이 있으면 간단한 데이터 확인이 매우 저렴합니다. 파일 끝에 줄 바꿈이없는 줄로 파일이 끝나면 파일이 손상되었음을 알 수 있습니다. 각 줄에 하나의 추가 바이트 만 있으면 CPU 시간없이 거의 정확하게 깨진 파일을 감지 할 수 있습니다.