텍스트 파일이 줄 바꿈으로 끝나야하는 이유는 무엇입니까?


1467

나는 여기의 모든 사람들이 모든 텍스트 파일이 줄 바꿈으로 끝나야한다는 속담에 익숙하다고 가정합니다. 나는이 "규칙"을 몇 년 동안 알고 있었지만 항상 궁금했습니다. 왜 그렇습니까?


30
이쑤시개. 파일 끝에 "새 줄"이 아닙니다. 마지막 줄의 끝에 "줄 바꿈"입니다. 또한 관련 질문에 대한 최상의 답변을 참조하십시오 : stackoverflow.com/questions/16222530/…
gcb

346
좀 더 nitpick하기 위해, 그는 실제로“new line”을 쓰지 않았고,“newline”을 썼습니다.
sindrenm

5
익숙하지는 않지만 실제로 불필요한 줄 바꿈이 실제로 내용을 깨뜨리는 사례의 수가 내 취향에 비해 너무 높기 때문에 궁금합니다.
tobibeer

2
현재 Node.js 스트림을 사용하여 일반 텍스트 데이터를 한 줄씩 구문 분석하고 있으며 스트림의 입력 측이 완료 될 때 추가 논리를 추가해야하기 때문에 터미널 줄 바꿈이 부족합니다. 마지막 행을 처리하기 위해 닫힙니다.
Mark K Cowan

23
유닉스 관련하여 방법 은 다음과 같이 파일의 끝에서의 일반적인 동작은 다음과 같습니다 \ n 문자가 라인을 시작하지 않는다; 대신, 그들은 그들을 끝냅니다. 따라서 \ n은 줄 구분자가 아니라 줄 종결 자입니다. 첫 줄 (모든 줄과 마찬가지로)을 시작하기 위해 \ n이 필요하지 않습니다. 마지막 줄 (모든 줄과 마찬가지로)을 끝내려면 \ n이 필요합니다. 파일 끝의 \ n은 추가 줄을 만들지 않습니다. 그러나 때로는 텍스트 편집기가 빈 줄을 추가 할 수 있습니다. 선택적으로 emacs도 그렇게 합니다.
MarkDBlackwell

답변:


1381

그것이 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유용한 명령을 만드는 것이 훨씬 어렵습니다. 파일을 연결하는 명령을 만드는 방법

  1. 그것은 각 파일의 시작을 새로운 줄에 넣습니다. 그것은 당신이 원하는 시간의 95 %입니다; 그러나
  2. 위의 예제에서 b.txtc.txt? 사이에서 두 파일의 마지막 줄과 첫 줄을 병합 할 수 있습니다 .

물론이는 풀 수 있지만의 사용 확인해야합니다 cat(위치 명령 행 인수, 예를 추가하여 더 복잡한을 cat a.txt --no-newline b.txt c.txt지금), 및 명령 보다는 다른 파일과 함께 붙여 넣기하는 방법을 각 개별 파일을 제어합니다. 이것은 거의 확실하지 않습니다.

… 또는 종료하지 않고 계속되는 줄을 표시하려면 특수한 센티넬 문자를 도입해야합니다. 글쎄, 이제 당신은 역행을 제외하고 POSIX와 같은 상황에 갇혀 있습니다 (행 종료 문자가 아닌 행 연속 문자).


자, 비 POSIX 호환 시스템 (요즘의 대부분의 Windows 것을), 요점은 논쟁은 다음과 같습니다 파일은 일반적으로 줄 바꿈으로 끝나지 않고, 예를 들어 줄 힘의 (비공식) 정의는 "있는 텍스트 여야 분리 줄 바꿈에 의해" (강조 표시). 이것은 전적으로 유효합니다. 그러나 구조화 된 데이터 (예 : 프로그래밍 코드)의 경우 구문 분석이 최소로 복잡해집니다. 일반적으로 구문 분석기를 다시 작성해야합니다. 파서가 원래 POSIX 정의를 염두에두고 작성된 경우 파서보다는 토큰 스트림을 수정하는 것이 더 쉬울 수 있습니다. 즉, 입력의 끝에 "인공 줄 바꿈"토큰을 추가하십시오.


9
POSIX는이 문제를 해결하기 위해 상당히 비실용적이지만,이 문제에 관한 질문의 수로 증거를 정의 할 때 POSIX가 실수를 범했다. 행은 <eol>, <eof> 또는 <eol> <eof>로 끝나는 0 개 이상의 문자로 정의되어야합니다. 파서의 복잡성은 유효한 문제가 아닙니다. 가능하면 프로그래머 헤드에서 라이브러리로 복잡성을 이동해야합니다.
Doug Coburn

23
@DougCoburn이 답변은 왜 이것이 잘못되었는지, POSIX가 왜 옳은지를 설명하는 철저하고 기술적 인 토론을했습니다. 불행히도 이러한 의견은 최근에 열렬한 중재자가 삭제 한 것 같습니다. 간단히 말해서 복잡성을 파싱하는 것이 아닙니다. 오히려 정의는 cat유용하고 일관된 방식 으로 도구를 작성하는 것을 훨씬 어렵게 만듭니다 .
Konrad Rudolph

8
@Leon POSIX 규칙은 가장 중요한 경우를 줄이는 것입니다. 그리고 그것은 매우 아름답습니다. 나는 실제로 사람들이 이것을 이해하지 못하는 방식에서 다소 손실을 입었습니다. 그것은 가능한 가장 단순하고 일관된 라인 정의입니다.
Konrad Rudolph

6
@ BT 더 편리한 워크 플로의 예가 결정 의 원인 이라고 가정합니다 . 그것은 단지 결과 일뿐입니다. 이유 는 POSIX 규칙이 간단한의 규칙이 있음을, 그리고 파서 가장 쉬운에서 처리 라인을 만든다. 우리가 토론을하고있는 유일한 이유는 Windows가 다르게 수행하기 때문에 POSIX 파일에서 실패하는 수많은 도구가 있기 때문입니다. 모두 POSIX를했다면 아무런 문제가 없을 것입니다. 그러나 사람들은 Windows가 아니라 POSIX에 대해 불평합니다.
Konrad Rudolph

7
@ BT POSIX 규칙이 의미가없는 경우를 지적하기 위해 Windows를 언급하고 있습니다 (즉, 뼈를 던졌습니다). 이 토론에서 다시 언급하지 않는 것이 더 행복합니다. 그러나 POSIX 플랫폼에서는 텍스트 파일을 생성 할 이유가 없기 때문에 다른 줄 끝 규칙을 사용하여 텍스트 파일을 논의하는 것은 의미가 없습니다. 장점은 무엇입니까? 말 그대로는 없습니다. — 요약하면, 이 답변 (또는 POSIX 규칙)이 생겨나는 증오를 실제로 이해하지 못합니다. 솔직히 말하면, 그것은 완전히 비이성적입니다.
Konrad Rudolph

282

각 줄은 마지막 줄을 포함하여 줄 바꿈 문자로 끝나야합니다. 줄 바꿈이 끝나지 않은 파일의 마지막 줄을 처리하는 데 문제가있는 프로그램이 있습니다.

GCC는 파일을 처리 할 없기 때문에 아니라 표준의 일부로 해야 하기 때문에 경고 합니다.

C 언어 표준에 따르면 비어 있지 않은 소스 파일은 줄 바꿈 문자로 끝나고 백 슬래시 문자 바로 앞에 오지 않아야합니다.

이것은 "shall"절이므로이 규칙을 위반하면 진단 메시지를 보내야합니다.

이것은 ANSI C 1989 표준의 2.1.1.2 섹션에 있습니다. ISO C 1999 표준 (그리고 아마도 ISO C 1990 표준)의 5.1.1.2 절.

참조 : GCC / GNU 메일 아카이브 .


17
쓰기 좋은 프로그램하시기 바랍니다 후, 사실 누락되지를 처리하는 동안 필요하거나 적절하다 사람을 ... "실종"처리 할 수있는 그 줄 바꿈을 삽입 할 수 그 중 하나
tobibeer

4
@BilltheLizard, "일부 프로그램은 파일이 줄 바꿈으로 끝나지 않으면 파일의 마지막 줄을 처리하는 데 문제가 있습니다"의 예는 무엇입니까 ?
Pacerier

4
@Pacerier wc -l는 줄 바꿈이 끝나지 않은 파일의 마지막 줄을 계산하지 않습니다. 또한 cat첫 번째 파일의 마지막 줄이 줄 바꿈이 아닌 경우 파일의 마지막 줄을 다음 파일의 첫 줄과 하나로 연결합니다. 구분 기호로 줄 바꿈을 찾는 거의 모든 프로그램이 이것을 망칠 가능성이 있습니다.
도마뱀 빌

2
@BilltheLizard, 나는 의미 wc했다 이미 언급되어 ....
Pacerier

2
내 나쁜, @BilltheLizard 명확히하기 : 문제가 줄 바꿈 (이미 대량 언급 한 같은 스레드에서되었는지 그 외에 종료되지 않은 경우 파일의 마지막 줄을 처리하는이 프로그램의 몇 가지 예는 무엇 catwc)?
Pacerier

116

이 답변은 의견이 아닌 기술적 답변을 시도한 것입니다.

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에 적용 할 때 자유롭게 게시하십시오.


2
POSIX 님은 질문에 태그되어 있지 않습니다 ... MVS / OS 줄 끝에 관한 질문? 또는 MS-DOS 줄 끝? 그건 그렇고, 알려진 모든 posix 시스템은 마지막 줄 끝이없는 텍스트 파일을 허용합니다 ( "text file"이 커널에서 특별한 처리를하여 posix 호환 주장 시스템이 발견되지 않은 경우 적절한 줄 바꿈을 삽입하지 않는 posix 호환 주장 시스템은 발견되지 않습니다)
Luis Colorado

62

다음의 차이점 과 관련이있을 수 있습니다 .

  • 텍스트 파일 (각 줄은 줄 끝으로 끝나야합니다)
  • 이진 파일 (알아야 할 실제 "줄"이 없으며 파일 길이를 유지해야합니다)

각 줄이 줄 끝으로 끝나는 경우 예를 들어 두 개의 텍스트 파일을 연결하면 첫 번째 줄의 마지막 줄이 두 번째 줄의 첫 줄로 바뀌지 않습니다.

또한 편집기는 파일이 줄 끝으로 끝나는 지 여부를로드에서 확인하고 파일을 로컬 옵션 'eol'에 저장 한 후 파일을 쓸 때이를 사용할 수 있습니다.

몇 년 최종 EOL, "잊지"는 않았다 (2005) 많은 편집자 (ZDE, 이클립스, Scite를, ...) 백업 매우 평가되지 않았습니다 .
뿐만 아니라 최종 EOL을 '새 줄 시작'으로 잘못 해석하고 실제로 다른 줄이 이미 존재하는 것처럼 표시하기 시작합니다.
위의 편집기 중 하나에서 파일을 여는 것과 비교할 때 vim과 같이 잘 작동하는 텍스트 편집기가있는 '적절한'텍스트 파일에서 매우 잘 보입니다. 파일의 실제 마지막 줄 아래에 여분의 줄이 표시되었습니다. 다음과 같은 것이 보입니다 :

1 first line
2 middle line
3 last line
4

11
+1. 이 문제가 발생하는 동안이 SO 질문을 찾았습니다. 이다 매우 이 "가짜"마지막 줄을 보여 이클립스의 성가신, 나는 그것을 제거하는 경우, 다음 이눔 (및 EOL을 기대하는 다른 모든 유닉스 도구)를 뿌려줍니다. 또한 이는 2005 년에만 해당되는 것이 아니라 Eclipse 4.2 Juno에도 여전히이 문제가 있습니다.
MestreLion


46

일부 도구는 이것을 기대합니다. 예를 들어 다음과 같이 wc예상됩니다.

$ echo -n "Line not ending in a new line" | wc -l
0
$ echo "Line ending with a new line" | wc -l
1

22
나는 "일부"라고 말하지 않을 것이며, 대부분의 도구는 텍스트 파일에 대해 모든 것이 아니라고 기대합니다. cat, git, diff, wc, grep, sed ... 목록은 엄청납니다
MestreLion

어쩌면 "라인"에 대한 대부분의 사람들의 직관적 인 이해와 반대로 단순히 "라인"에 대한 POSIX 정의 내에서 작동하는 한, 이것을 기대wc 하지 않을 수도 있습니다.
Guildenstern

@Guildenstern 직관적 인 정의는 두 경우 모두 wc -l를 인쇄 1하는 것이지만 일부 사람들은 두 번째 경우를 인쇄해야한다고 말할 수 있습니다 2.
Flimm

@Flimm \nPOSIX / UNIX와 같이 줄 구분 기호가 아닌 줄 종결 자로 생각 하면 2를 인쇄하는 두 번째 경우를 기대하는 것은 절대적으로 미칩니다.
세미콜론

21

기본적으로 최종 EOL EOF를 얻지 못하면 파일을 올바르게 처리하지 못하는 많은 프로그램이 있습니다.

GCC는 C 표준의 일부로 예상되므로 이에 대해 경고합니다. (섹션 5.1.1.2)

"파일 끝에 줄 바꿈 없음"컴파일러 경고


5
GCC는 파일을 처리 할 수 ​​없으며 C 표준의 일부로 경고를 표시해야합니다.
Bill the Lizard

IIRC, MSVC 2005는 불완전한 행으로 끝나고 컴파일을 거부 한 C 파일에 대해 불평했습니다.
Mark K Cowan

16

이것은 단순한 터미널이 사용 된 초기부터 시작되었습니다. 개행 문자는 전송 된 데이터의 '플러시'를 트리거하는 데 사용되었습니다.

오늘날 개행 문자는 더 이상 필요하지 않습니다. 물론 개행이 없으면 많은 앱에 여전히 문제가 있지만 해당 앱의 버그로 간주합니다.

그러나 줄 바꿈 이 필요한 텍스트 파일 형식이 있으면 간단한 데이터 확인이 매우 저렴합니다. 파일 끝에 줄 바꿈이없는 줄로 파일이 끝나면 파일이 손상되었음을 알 수 있습니다. 각 줄에 하나의 추가 바이트 만 있으면 CPU 시간없이 거의 정확하게 깨진 파일을 감지 할 수 있습니다.


15
요즘 텍스트 파일에 대한 EOF의 줄 바꿈은 필수 사항은 아니지만 대부분의 유닉스 도구가 일관된 결과와 함께 작동하도록 하는 유용한 규칙 입니다. 전혀 버그가 아닙니다.
MestreLion

14
우리 중 많은 사람들이 유닉스 도구를 전혀 사용하지 않으며 신경 쓰지 않습니다.
DaveWalley

12
유닉스 도구 일뿐 만 아니라 합리적인 파일 형식을 가정 할 수 있다면 모든 도구가 더 잘 작동하거나 더 간단하게 코딩됩니다.
Sam Watkins '12

2
@Sam Watkins 잘 정의 된 간단한 형식을 갖는 것이 좋습니다. 그러나 코드는 여전히 데이터 가 형식을 준수 한다고 가정 할 필요는 없습니다 .
chux-복원 Monica Monica

8
@MestreLion 이것은 바보 같은 표준을 준수하는 나쁜 도구 세트에서 쓸모없는 유산 입니다. 이러한 극단 주의적 프로그래밍의 인공물 (즉, 모든 파일, 모든 것이 평범한 텍스트를 말해야한다!)은 특정 역사 순간에 유일하게 이용 가능한 도구이기 때문에 발명 직후에 죽지 않았다. C는 C ++로 대체되었으며 POSIX의 일부가 아니며 EOF에서 EOL이 필요하지 않으며 * nix luddists에 의해 사용이 권장되지 않습니다.
polkovnikov.ph

14

별도의 유스 케이스 : 텍스트 파일이 버전 제어되는 경우 (이 경우 특히 git에서 다른 파일에도 적용됨). 내용이 파일 끝에 추가되면 이전 줄의 마지막 줄이 줄 바꿈 문자를 포함하도록 편집됩니다. 즉, blame해당 행이 마지막으로 편집 된 시간을 찾기 위해 파일을 열면 실제로보고자하는 커밋이 아니라 텍스트 추가가 표시됩니다.


1
diff와 blame은 "newlines"( \n)가 아닌 "new lines"을 탐지하도록 업데이트되어야합니다 . 문제 해결됨.
Andrew

1
-w 태그를 사용하여 공백 변경 사항을 무시할 수 있지만 기본값은 아닙니다.
Robin Whittleton

11

위의 실제적인 이유 외에도 Unix (Thompson, Ritchie 등) 또는 Multics의 선임자들이 줄 구분 기호보다 줄 종결자를 사용하는 이론적 인 이유가 있음을 깨달았을 때 놀라지 않을 것입니다. 터미네이터를 사용하면 가능한 모든 행 파일을 인코딩 할 수 있습니다. 줄 구분 기호를 사용하면 줄이 0 인 파일과 빈 줄이 하나 포함 된 파일간에 차이가 없습니다. 둘 다 0 문자를 포함하는 파일로 인코딩됩니다.

따라서 그 이유는 다음과 같습니다.

  1. 그것이 POSIX가 정의하는 방식이기 때문입니다.
  2. 일부 도구는 도구가 없으면 도구가 필요하거나 "오작동"하기 때문입니다. 예를 들어, wc -l줄 바꿈으로 끝나지 않으면 최종 "줄"을 계산하지 않습니다.
  3. 간단하고 편리하기 때문입니다. 유닉스에서는 cat제대로 작동하며 합병증없이 작동합니다. 해석 할 필요없이 각 파일의 바이트 만 복사합니다. 에 해당하는 DOS가 있다고 생각하지 않습니다 cat. 를 사용 copy a+b c하면 파일의 마지막 줄이 파일 a의 첫 줄과 병합 됩니다.b .
  4. 제로 라인의 파일 (또는 스트림)은 하나의 빈 라인의 파일과 구별 될 수 있기 때문에.

11

나는 이것을 몇 년 동안 스스로 궁금해했다. 그러나 나는 오늘 좋은 이유를 발견했습니다.

모든 줄에 레코드가있는 파일을 상상해보십시오 (예 : CSV 파일). 그리고 컴퓨터는 파일 끝에서 레코드를 쓰고있었습니다. 그러나 갑자기 추락했다. 마지막 줄이 완성 되었나요? (좋은 상황이 아닙니다)

그러나 항상 마지막 줄을 끝내면 알 수 있습니다 (마지막 줄이 종료되었는지 간단히 확인하십시오). 그렇지 않으면 우리는 아마 마지막 줄을 버릴 것입니다.


10

아마도 일부 파싱 코드가 거기에있을 것으로 예상했을 것입니다.

나는 그것이 "규칙"으로 간주 될지 확신하지 못하며, 확실히 내가 종교적으로 고수하는 것이 아니다. 대부분의 현명한 코드는 마지막 줄에서 줄 바꿈없이 또는 줄 바꿈없이 텍스트 (인코딩 포함)를 한 줄씩 (줄 끝 선택) 구문 분석하는 방법을 알고 있습니다.

실제로-새로운 줄로 끝나는 경우 : 이론적으로 EOL과 EOF 사이에 빈 마지막 줄이 있습니까? 하나는 숙고 ...


12
그것은는 협약, 규칙 아니다하십시오 라인이 뭔가하고 있음과 끝 끝 (end-of-line) . 따라서 EOL과 EOF 사이에는 "빈 최종 라인"이 없습니다.
MestreLion

4
@MestreLion : 그러나 해당 문자의 이름은 "줄 끝"이 아니라 "줄 바꿈"및 / 또는 "줄 바꿈"입니다. 줄 종결자가 아닌 줄 구분자입니다. 그리고 결과는 마지막 빈 줄입니다.
벤 Voigt

2
(sane) 도구는 파일의 마지막 EOL (CR, LF 등)을 빈 줄로 추가하지 않습니다. 그리고 끝점 EOL이 없으면 모든 POSIX 도구는 파일의 마지막 문자를 한 줄로 계산하지 않습니다. 에 관계없이 EOL 문자의 이름은 "줄 바꿈"또는 "캐리지 리턴"인 분별 도구 라인으로 취급 모든 실제적인 목적들을 위해, ( "줄 바꿈"라는 이름의 문자가 없다) 종료 하지 라인으로, 분리기 .
MestreLion 2016 년

2
@MestreLion, "라인 터미네이터"가 제정신입니까? 비 프로그래머 몇 명을 잡고 빠른 조사를하십시오. 선의 개념이 "선 구분 기호"의 개념에 더 가깝다는 것을 빨리 알 수 있습니다. "라인 터미네이터"의 개념은 이상 합니다.
Pacerier

4
@ Sahuagin : 이것은 견해 가 아니며 POSIX 표준이 선을 정의하는 방법입니다. 0 바이트의 빈 파일에는 0 줄이 있으므로 EOL이 없으며 하나의 빈 줄만있는 것으로 간주되는 파일 에는 EOL 필요합니다. 또한 EOL이 있는지 여부에 관계없이 모든 편집기에서 다음 (또는 첫 번째) 행으로 "가져올"수 있도록하기 때문에 파일의 행 을 계산 하려는 경우에만 관련이 있습니다 .
MestreLion

10

마지막에는 줄 바꿈이없는 파일에 대한 실제 프로그래밍 문제가 있습니다 read.Bash 내장 (다른 read구현에 대해서는 모른다 )이 예상대로 작동하지 않습니다.

printf $'foo\nbar' | while read line
do
    echo $line
done

이 인쇄 foo ! 그 이유는 read마지막 줄을 만나면 내용을 $line쓰지만 EOF에 도달했기 때문에 종료 코드 1을 반환하기 때문입니다. 이로 인해 while루프 가 끊어 지므로 echo $line부품에 도달하지 못합니다 . 이 상황을 처리하려면 다음을 수행해야합니다.

while read line || [ -n "${line-}" ]
do
    echo $line
done < <(printf $'foo\nbar')

즉, 파일 끝에서 비어 있지 않은 행으로 인해 실패한 echo경우 수행 read하십시오. 당연히이 경우 출력에 입력에없는 새로운 줄 바꿈이 하나 더 생깁니다.


9

(텍스트) 파일이 줄 바꿈으로 끝나야하는 이유는 무엇입니까?

많은 사람들이 잘 표현한 이유는 다음과 같습니다.

  1. 많은 프로그램이 제대로 작동하지 않거나 실패하면 실패합니다.

  2. 파일을 잘 처리하는 프로그램에도 결말이 없기 때문에 '\n'도구의 기능은 사용자의 기대에 미치지 못할 수 있습니다.이 경우에는 분명하지 않습니다.

  3. 프로그램은 거의 최종적인 것을 허용'\n' 하지 않습니다 (아무도 모르겠습니다).


그러나 이것은 다음 질문을 제기합니다.

줄 바꿈없이 텍스트 파일에 대해 코드는 어떻게해야합니까?

  1. 가장 중요- 텍스트 파일이 줄 바꿈으로 끝나는 것으로 가정하는 코드를 작성하지 마십시오 . 파일이 형식을 준수 한다고 가정하면 데이터 손상, 해커 공격 및 충돌이 발생합니다. 예:

    // Bad code
    while (fgets(buf, sizeof buf, instream)) {
      // What happens if there is no \n, buf[] is truncated leading to who knows what
      buf[strlen(buf) - 1] = '\0';  // attempt to rid trailing \n
      ...
    }
    
  2. 마지막 후행 '\n'이 필요한 경우 사용자에게 부재와 조치를 알려줍니다. 파일 형식을 확인하십시오. 참고 : 여기에는 최대 줄 길이, 문자 인코딩 등에 대한 제한이 포함될 수 있습니다.

  3. 결측 된 final 처리하는 코드 처리를 명확하게 정의하십시오 '\n'.

  4. 가능한 결말이없는 파일을 생성 하지 마십시오 '\n'.


4

여기는 매우 늦었지만 파일 처리에서 하나의 버그에 직면했으며 파일이 빈 줄 바꿈으로 끝나지 않기 때문에 발생했습니다. 우리는 텍스트 파일을 처리하고 sed있었고sed 있었고 출력에서 ​​마지막 줄을 생략하여 유효하지 않은 json 구조를 일으키고 나머지 프로세스를 실패 상태로 보냈습니다.

우리가하고있는 일은 :

하나의 샘플 파일이 있습니다 : foo.txtjson안에 내용이 있습니다.

[{
    someProp: value
},
{
    someProp: value
}] <-- No newline here

파일은 미망인 컴퓨터에서 생성되었으며 창 스크립트는 PowerShell 명령을 사용하여 해당 파일을 처리했습니다. 문제 없다.

sed명령을 사용하여 동일한 파일을 처리했을 때sed 's|value|newValue|g' foo.txt > foo.txt.tmp

새로 생성 된 파일은

[{
    someProp: value
},
{
    someProp: value

붐은 잘못된 JSON으로 인해 나머지 프로세스에 실패했습니다.

따라서 항상 빈 줄 바꿈으로 파일을 끝내는 것이 좋습니다.


3

나는 항상 줄 바꿈없이 파일을 파싱하는 것이 어려웠던 시절부터 규칙이 왔다는 인상을 받았다. 즉, EOL 문자 또는 EOF로 행 끝을 정의한 코드를 작성하게됩니다. EOL로 끝나는 라인을 가정하는 것이 더 간단했습니다.

그러나 나는 규칙이 개행을 요구하는 C 컴파일러에서 파생되었다고 생각합니다. "파일 끝에 줄 바꿈 없음"컴파일러 경고에서 지적한 것처럼 #include는 줄 바꿈을 추가하지 않습니다.


0

다른 프로세스에서 파일을 생성하는 동안 파일이 처리되고 있다고 가정하십시오.

그것과 관련이 있을까요? 파일을 처리 할 준비가되었음을 나타내는 플래그입니다.


-4

나는 개인적으로 소스 코드 파일 끝에 줄 바꿈을 좋아합니다.

그 문제에 대해 Linux 또는 모든 UNIX 시스템에서 유래했을 수 있습니다. 소스 코드 파일이 빈 줄 바꿈으로 끝나지 않았기 때문에 컴파일 오류가 있습니다 (실수하지 않은 경우 gcc). 왜 이런 식으로 만들어 졌습니까?


-6

IMHO, 그것은 개인적인 스타일과 의견의 문제입니다.

옛날에는 그 개행을 넣지 않았습니다. 저장된 문자는 14.4K 모뎀을 통해 더 빠른 속도를 의미합니다.

나중에 Shift + 아래쪽 화살표를 사용하여 최종 줄을 쉽게 선택할 수 있도록 줄 바꿈을 넣었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.