일치하는 패턴 뒤에 일부 텍스트를 추가할 때 내용의 나머지 부분과 추가 내용을 분리하기 위해 주석이 포함된 빈 줄을 추가하고 싶습니다. 그러나 첫 번째 항목에서는 추가 (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
( a
sed 명령 다음에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)과 같이 작성됩니다 .\n
sed
sed
bash
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
, i
및 c
)은 모두 동일한 방식으로 작동합니다. 선행 공백은 무시되고 텍스트가 로 시작하면 \
삭제됩니다. 기본적으로 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 ();