sed의 첫 번째 추가 개행 문자에는 추가 백슬래시가 필요합니다.

sed의 첫 번째 추가 개행 문자에는 추가 백슬래시가 필요합니다.

일치하는 패턴 뒤에 일부 텍스트를 추가할 때 내용의 나머지 부분과 추가 내용을 분리하기 위해 주석이 포함된 빈 줄을 추가하고 싶습니다. 그러나 첫 번째 항목에서는 추가 (make it ) \n를 사용하여 이스케이프해야 했지만 추가된 나머지 텍스트에는 분명히 필요하지 않다는 것을 알았습니다 .\\\\n왜 그럴까요?

SUSE 11 서버(bash v3.2.57(2) 및 GNU sed 버전 4.1.5)에서 생성한 예는 다음과 같습니다.

edwdev@hdpedge1:/edw> sed '/test/a \\nNot a test\nJust Playing' <<< test
test

Not a test
Just Playing

첫 번째 항목을 이스케이프하지 않으면 \n( ased 명령 다음에N포장 대신 인쇄하세요.

edwdev@hdpedge1:/edw> sed '/test/a \nNot a test\nJust Playing' <<< test
test
nNot a test
Just Playing

a실수로 대체 구문과 충돌하지 않도록 명령 뒤에 의도적으로 공백을 추가했습니다 .

\n으로 바꾸면 동일한 동작이 관찰됩니다 \t. 명령 뒤의 공백 수는 a중요하지 않은 것 같습니다. 공백이 여러 개 있어도 특수 문자를 인쇄하려면 첫 번째 백슬래시를 이스케이프해야 합니다.


이는 처음에 관찰한 다른 환경에서도 마찬가지였습니다. Centos 7 x64 VM, bash 버전은 4.2.46(2), sed 버전은 GNU sed 4.2.2였습니다.

sed -i '/\[mysqld\]/a \\n# <<INSERTED MANUALLY>>\ntransaction-isolation=READ-COMMITTED\ninnodb_flush_method=O_DIRECT\nmax_connections=550\n# <<END OF MANUAL INSERTIONS >>\n' /etc/my.cnf

산출:

...
[mysqld]

# <<INSERTED MANUALLY>>
transaction-isolation=READ-COMMITTED
innodb_flush_method=O_DIRECT
max_connections=550
# <<END OF MANUAL INSERTIONS >>

...

먼저 출력을 이스케이프 해제합니다.\n:

[mysqld]
n# <<INSERTED MANUALLY>>
transaction-isolation=READ-COMMITTED
innodb_flush_method=O_DIRECT
max_connections=550
# <<END OF MANUAL INSERTIONS >>

이런 행동을 하는 특별한 이유가 있나요? 문서를 탐색하는 동안 자세한 내용을 찾을 수 없습니다(여기), 물론 나는 전체 문서를 철저하게 읽지 않았습니다.

답변1

기준a명령의 형태 sed

a\
text to be appended

c명령과 i동일한 형식을 따릅니다 .

더 많은 줄을 추가하려면 각 줄에서 줄바꿈을 이스케이프 처리해야 합니다.

a\
text to\
be appended

표준은 GNU처럼 개행 문자를 해석하는 방법을 sed모르므 로 GNU가 아닌 것을 사용하는 한 줄 명령은 (in)과 같이 작성됩니다 .\nsedsedbash

sed $'/test/a\\\n\\\nNot a test\\\nJust Playing\n' <<<test

여기서는 $'...'쉘을 사용하여 모든 것을 \n실제 개행 문자 \\\.

$'...'이 명령은 다음 형식으로 작성할 수 있지만 다음 기능 은 없습니다 bash.

sed '/test/a\
\
Not a test\
Just Playing
' <<<test

이 두 명령은 GNU에서도 작동합니다 sed.

GNU는 sed추가적으로 이전 텍스트와 개행 문자 사이에 개행 문자를 삽입하지 않고도 추가 텍스트가 나타날 수 있도록 허용 하고 완전한 삭제를 a허용합니다 .\\그러나 명령 바로 뒤에 오는 명령은 명령 a의 표준 형식에서 백슬래시 로 해석됩니다.a\(이것은 귀하의 질문에 대한 기본 문제입니다). GNU는 sed또한 스크립트에 추가된 텍스트 끝에 줄바꿈을 추가합니다. 따라서 GNU를 사용하면 sed다음과 같이 작성할 수 있습니다.

sed '/test/a\ \
Not a test\
Just Playing' <<<test

sed또는 GNU가 알고 있다는 사실을 활용하여 \n,

sed '/test/a\\nNot a test\nJust Playing' <<<test

답변2

이는 정확히 문서화된 동작은 아니지만 모든 것이 확장입니다. 세 가지 확장 유사 명령( a, ic)은 모두 동일한 방식으로 작동합니다. 선행 공백은 무시되고 텍스트가 로 시작하면 \삭제됩니다. 기본적으로 sed가 다음 형식 중 어떤 형식을 사용하는지는 중요하지 않습니다.

i foo
i \foo
i \
foo

그들은 모두 동일합니다. (나는 i여기에 익숙하다는 것을 알고 있지만 설명을 확인하십시오 a. i그리고 c- 그것은 초현실적입니다.)

그리고암호다음과 같이 표시됩니다.

1111         case 'a':
1112         case 'i':
1113         case 'c':
1114           ch = in_nonblank ();
1115 
1116         read_text_to_slash:
1117           if (ch == EOF)
1118             bad_prog (_(EXPECTED_SLASH));
1119 
1120           if (ch == '\\')
1121             ch = inchar ();

관련 정보