\ r과 \ n의 이론적 근거는 s 명령에서 다른 것을 의미합니까?


13

검색 할 때 \n줄 바꿈이며 \r캐리지 리턴 ( ^M)이지만 교체 할 때 \r줄 바꿈 \n은 null 바이트 ( ^@)입니다.

이 비대칭의 기원은 무엇입니까? 이 행동이 ... 최소한 말로 특이한 점을 감안할 때 (그리고 처음 잘못했을 때 상당히 비생산적 인) 나는 기괴한 역사적 이유가 있다고 생각합니다.

(실제로이 동작을 "수정"하고 더 직관적 인 것을 얻을 수있는 방법이 있습니까?)

답변:


10

가장 기본적인 수준에서, :substitute전자는 정규식이고 후자는 텍스트이며 특정 추가 이스케이프 시퀀스 가 있기 때문에 검색과 바꾸기 부분 사이에 이미 비대칭 성이 있습니다. 이것은 당신이 \n의미 하는 직관에 의해 강조됩니다 .

예를 들어, \n검색에서 리터럴과 일치하지 않는 것을 고려 하십시오 \n. 이되는 라인 (EOL) 바이트 순서의 끝과 일치 \r, \r\n또는 막 \n상의 따라 'fileformat'버퍼를.

\r"EOL 삽입"을 의미하는 이유 는 그 뒤에 몇 가지 이력 이 있습니다. Vi는 파일에서 NUL 바이트를 처리 할 방법이 없었습니다. Vim은 내부적으로 NUL 바이트를 NL 바이트로 대체함으로써 개선되었습니다 (C 문자열은 NUL로 구분되므로).

대체에서 NUL 바이트를 나타내는 데 사용되는 해당 라인의 내부 표현에 간단하게 삽입 :substitute되기 때문에이 구현 세부 사항이 동작에 누출되었습니다 \n. \r내부 라인을 2 개로 나누고 EOL을 삽입합니다. Vim은 실제로 EOL 바이트를 메모리에 저장하지 않고 대신 버퍼를 읽거나 쓸 때 직렬화를 해제합니다.

많은 사용자의 많은 스크립트와 근육 메모리를 손상시키지 않으면 지금은 변경할 수 없습니다. 고맙게도에 문서화되어 :help sub-replace-special있습니다.


6

NUL바이트 C에서 문자열 종료하고, 이런 이유로 빔 매뉴얼에서의 설명이 규칙을 사용한다 :h NL-used-for-Nul:

파일의 <Nul> 문자는 메모리에 <NL>로 저장됩니다. 디스플레이에서 "^ @"로 표시됩니다. 파일을 읽고 쓸 때 번역이 수행됩니다. <Nul>을 검색 패턴과 일치 시키려면 CTRL- @ 또는 "CTRL-V 000"을 입력하면됩니다. 이것은 아마도 당신이 기대하는 것입니다. 내부적으로 문자는 검색 패턴에서 <NL>으로 바뀝니다. CTRL-V를 입력하면 CTRL-J도 <NL>을 삽입하여 파일에서 <Nul>을 검색합니다. {Vi는 파일에서 <Nul> 문자를 전혀 처리 할 수 ​​없습니다}

이 규칙은 :s/.../.../명령에는 영향을 미치지 만 substitute()기능 에는 영향을 미치지 않습니다 . \r\n교체에 문자열 substitute()호출은 원래의 의미를 유지한다.

나는 행동에 대한 더 깊은 이유가 있다고 생각하지 않습니다. Vim은 단순히 원본에서 유기적으로 진화했습니다 vi. 그에 대한 큰 청사진은 없었으며 기능은 서로의 상단에 쌓여 있었고 조직화를 위해 상대적으로 적은 노력을 기울였습니다.


0

다른 Vi 클론은 대체를 지원하지 \r않거나 \n(실제 백 슬래시와 문자로) 행을 두 줄로 나누는 실수 ^M( CTRL-V Enter) 의미의 동작표준 동작입니다 .

repl에 <carriage-return>을 입력하면 ( ex 모드 에서 이스케이프 <backslash>가 필요하고 open 또는 vi 모드 에서 이스케이프 <control> -V가 필요 ) 편집 버퍼에 새 줄이 만들어집니다. . <캐리지 리턴>은 폐기됩니다.

유닉스 히스토리 아카이브에서 BSD ex / vi의 첫 번째 버전은 4.1cBSD ( @(#)ex_re.c 7.2 10/16/81이며 4BSD ( @(#)ex_re.c 6.2 10/23/80)에는 없다 [4.1a와 4.1b는 아카이브에 없다].

관련 코드는 다음과 같습니다

/* ^V <return> from vi to split lines */
if (c == '\r')
    c = '\n';

이것은 뉴스 파일 에서도 언급 됩니다 .

rhs에서 ^ V <return>을 사용하여 vi에서 대체 명령을 사용하여 행을 분할 할 수 있습니다. ex 명령 모드를 사용하는 마지막 이유는 다음과 같습니다.

ex 명령 모드에서 이전에 지원 된 동작은 백 슬래시 입력 (즉, 백 슬래시 다음에 실제 줄 바꿈)이 개행을 삽입하는 것입니다.


0

비대칭의 기원은 컴퓨팅 히스토리로 돌아갑니다.

짧은 버전 :

<CR> & <LF>  (Carriage-Return and Linefeed) 
== 
\r & \n

긴 버전 :
첫 번째 화면은 기본적으로 TTY (Teletype)의 디지털 버전이며 프린터와 유사한 동작을 생성하기 위해 제어 코드를 사용했습니다. 캐리지 리턴은 커서 (또는 프린트 헤드)를 시작 열로 가져갔습니다. 줄 바꿈이 다음 행 (화면)으로 진행되어 용지를 한 줄 앞으로 넣습니다.

프린터의 경우 짝을 이루어야 <CR><LF>합니다. 그렇지 않으면 출력이 제대로 보이지 않습니다. 초기 화면에서이 문제는 여전히 유효했습니다.

DOS (및 sorta-Windows 이후)는 이전 표준을 따르고로 텍스트를 저장합니다 <CRLF>.

* NIX 텍스트 (대부분의 vi 사용자에게 친숙 함)는 <LF>효율성을 위해서만 사용 합니다.

Windows에서 테스트하려면 Word / Wordpad를 사용하고 "행 : 텍스트-MS-DOS 형식"으로 몇 줄의 텍스트를 저장하십시오. 그런 다음 메모장에서 동일한 파일을여십시오. 정상적으로 보일 것입니다. 그런 다음 동일한 파일을 Word / Wordpad에 "유형 : 텍스트"로 저장하십시오. 메모장은 모든 줄 바꿈을 무시하고 줄을 함께 실행합니다. [메모장의 텍스트 형식은 기본적으로 \r\n조합으로 설정되고 Word / Wordpad는 기본적으로 조합으로 설정됩니다 \n.]

\ r은 <CR>

\ n은 다음과 같은 코드입니다. <LF>

그리고 vi에 대한 나의 (매우 제한된) 경험에서, 그것은 <CRLF>내 DOS 텍스트 편집기에서 조합 을 "수정"하려고합니다 . vi가 하나의 문자를 제거하고으로 대체되었습니다 <NUL>. vi 사용을 중단 한 이유의 대부분.


2
모든 정보가 흥미 동안 이유, 그것은 단지 이야기 \r입니다 <CR>하고 \n있다 <LF>. 그것은 왜의 실제 문제가 해결되지 않는 \n\r행동을 다르게 서로 다른 맥락에서입니다.
텀블러 41

감사합니다! :-) 당신이 대답했을 때 나는 그것을 바꾸고 있었다. (마지막 단락 추가)
Robin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.