답변:
가장 기본적인 수준에서, :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
있습니다.
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
. 그에 대한 큰 청사진은 없었으며 기능은 서로의 상단에 쌓여 있었고 조직화를 위해 상대적으로 적은 노력을 기울였습니다.
다른 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 명령 모드에서 이전에 지원 된 동작은 백 슬래시 입력 (즉, 백 슬래시 다음에 실제 줄 바꿈)이 개행을 삽입하는 것입니다.
비대칭의 기원은 컴퓨팅 히스토리로 돌아갑니다.
짧은 버전 :
<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 사용을 중단 한 이유의 대부분.
\r
입니다<CR>
하고\n
있다<LF>
. 그것은 왜의 실제 문제가 해결되지 않는\n\r
행동을 다르게 서로 다른 맥락에서입니다.