내 인상은POSIX 사양sed
i\
출력에서 선행 공백을 원하지 않는 한, 명령 다음 행의 텍스트를 왼쪽 정렬해야 합니다.
내 Mac에서 (BSD sed를 사용하여) 빠른 테스트를 통해 이것이 가능하다는 것을 알 수 있습니다.아니요필요한:
$ cat test.sed
#!/bin/sed -f
i\
This line starts with spaces.
$ echo some text | sed -f test.sed
This line starts with spaces.
some text
$
하지만 이 기록은 어디서도 찾을 수 없는 것 같습니다. POSIX 사양이나 sed
내 시스템의 매뉴얼 페이지 에도 없습니다 .
sed
이식하려는 스크립트에서 이 동작을 신뢰할 수 있습니까? 휴대성은 얼마나 되나요?
(기록이 있는지어딘가에?)
sed
(보너스 질문: 에 전달된 고정 줄의 시작 부분에 공백을 강제로 삽입할 수 있습니까 i\
?)
답변1
아니요. 하지만 선행 공백을 피하는 한 스크립트는 이식 가능합니다. 왜? 일부 sed
는 텍스트 줄에서 공백 문자를 제거하기 때문에 이를 방지하는 유일한 방법은 지난 세기의 이 매뉴얼 페이지에서 설명하는 것처럼 선행 공백을 피하는 것입니다.1,2,삼
아카이브를 확인하고 읽으면 동일하게 적용됩니다 BSD
sed
( OSX
코드를 복사했을 뿐이며 확장자가 아님).man
페이지:BSD 2.11
매우 명확한:
(1)나\
텍스트
.......
로 표현되는 매개변수텍스트'\'
하나 이상의 줄로 구성되며 마지막 줄을 제외한 모든 줄은 숨겨진 개행 문자로 끝납니다. 텍스트의 백슬래시는's'
명령 대체 문자열에서 백슬래시로 처리되며 모든 스크립트 줄에서 발생하는 제거로부터 초기 공백과 탭을 보호하는 데 사용할 수 있습니다.
이제 POSIX 사양의 어디에 문서화되어 있습니까? 그것은 단지 말한다
매개변수 텍스트는 하나 이상의 줄로 구성되어야 합니다. 텍스트에 포함된 각 <newline> 앞에는 <backslash>가 와야 합니다. 텍스트의 다른 <백슬래시> 문자는 제거해야 하며 후속 문자는 문자 그대로 처리해야 합니다.
아래로 스크롤하면근본적인그것은 말한다
명령줄에서 <공백> 및 <공백> 문자를 허용해야 한다는 요구 사항은 과거의 관행을 명확하게 설명하고 "초기 공백 [원문] 및 탭 문자가 제거되지 않도록 보호"라는 문구에 대한 혼란을 없애기 위해 이전 제안보다 더 명확해졌습니다. sed 유틸리티 텍스트를 설명하는 많은 기록 문서에 나타납니다. (모든 구현이 명령줄에서 이를 허용하지만 텍스트 줄에서 <공백> 문자를 제거하는 것으로 알려진 것은 아닙니다. 주소 앞에는 선행 <공백> 문자).
관련된 부분이기 때문에"백슬래시를 사용할 수 있습니다."이 인용문에는 포함되지 않았으며 나머지 문구는"초기 공백을 보호하세요..."말도 안 돼... 1
어쨌든 요약하면 일부 구현에서는 텍스트 줄에서 공백을 제거했습니다(그리고 일부는 여전히 수행합니다). 그러나 모든 구현이 준수해야 하는 POSIX 사양으로 인해
텍스트의 다른 <백슬래시> 문자는 제거해야 하며 후속 문자는 문자 그대로 처리해야 합니다.
삽입할 텍스트의 줄을 들여쓰기하는 이식 가능한 방법은 각 줄의 선행 공백을 이스케이프 처리하는 것이라고 결론 내릴 수 있습니다.
OSX
1: 나는 또한 사람들 이 소스 코드를 변경하지 않고 페이지의 전체 단락을 BSD
변경하는 이유를 이해하지 못합니다. 이전과 동일한 동작을 얻지만 이를 문서화하는 man 섹션은 더 이상 존재하지 않습니다.man
답변2
표준 동작이 아닌 OSX 확장입니다 sed
. 너는 볼 수있어이 링크는 기능적으로compile_text
:
/*
* Compile the text following an a or i command.
*/
static char *
compile_text()
{
int asize, size;
char *text, *p, *op, *s;
char lbuf[_POSIX2_LINE_MAX + 1];
asize = 2 * _POSIX2_LINE_MAX + 1;
text = xmalloc(asize);
size = 0;
while (cu_fgets(lbuf, sizeof(lbuf))) {
op = s = text + size;
p = lbuf;
EATSPACE();
for (; *p; p++) {
if (*p == '\\')
p++;
*s++ = *p;
}
size
그들은 EATSPACE
공간을 차지하기 위해 매크로를 사용합니다.
FreeBSD에서는 , 를 사용할 때 줄 연속 문자로 sed
잘못 처리되어 동작이 더욱 이상해지는 경우가 있습니다 . \
내 FreeBSD 9.3에서:a
i
c
$ echo 1 | sed -e 'i\ 1'
": extra characters after \ at the end of i command
하지만:
$ echo 1 | sed -e 'i\
2'
2
1
효과적이며 공간도 차지합니다.
GNU sed
, Heirloom에는 sed
이 문제가 없습니다.
답변3
강암가장 좋은 답변을 주었습니다, 하지만 참고로 여기에는암소 비슷한 일종의 영양 sed
하다:
echo foo | sed 'i\
This line starts with spaces.'
산출:
This line starts with spaces.
foo