[shell] sed를 사용하여 첫 번째 일치 후 줄 삽입

어떤 이유로 나는 이것에 대한 직접적인 대답을 찾을 수없는 것처럼 보이며 현재 약간의 시간 위기에 처해 있습니다. sed명령을 사용하여 특정 문자열과 일치하는 첫 번째 줄 뒤에 선택 텍스트 줄을 삽입하는 방법은 무엇입니까 ? 나는 가지고있다 …

CLIENTSCRIPT="foo"
CLIENTFILE="bar"

그리고 줄 뒤에 줄을 삽입하고 싶습니다 CLIENTSCRIPT=

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"



답변

GNU sed를 사용하여 이것을 시도하십시오 :

sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

in-place 를 대체 하려면 다음을 사용하십시오.

sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

산출

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"

문서


답변

표준 sed구문에 유의하십시오 (POSIX에서와 같이 모든 호환 sed구현 (GNU, OS / X, BSD, Solaris …)에서 지원) :

sed '/CLIENTSCRIPT=/a\
CLIENTSCRIPT2="hello"' file

또는 한 줄로 :

sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file

( sed 스크립트 해석 을 구성하기 위해 -expressions (및 -files 의 내용 )이 개행과 결합됩니다 sed).

-i내부 편집에 대한 옵션도 지원 (FreeBSD의의와 같은) GNU 확장, 다른 구현입니다 -i ''그합니다.

또는 이식성을 위해 perl대신 사용할 수 있습니다 .

perl -pi -e '$_ .= qq(CLIENTSCRIPT2="hello"\n) if /CLIENTSCRIPT=/' file

또는 당신은 사용할 수 있습니다 ed또는 ex:

printf '%s\n' /CLIENTSCRIPT=/a 'CLIENTSCRIPT2="hello"' . w q | ex -s file


답변

다음 s명령을 사용하여 POSIX 호환 제품 :

sed '/CLIENTSCRIPT="foo"/s/.*/&\
CLIENTSCRIPT2="hello"/' file


답변

MacOS (최소한 OS 10)와 Unix에서 모두 작동하는 Sed 명령 (예 : Gilles (현재 허용되는 것)과 같이 압축이 필요하지 않음) :

sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file

이것은 bash와 $ ‘\ n’평가 견적 스타일을 알고있는 다른 쉘에서도 작동합니다. 모든 것은 한 줄에있을 수 있으며 이전 / POSIX sed 명령에서 작동합니다. CLIENTSCRIPT = “foo”(또는 동등한 항목)와 일치하는 여러 행이있을 수 있으며 처음으로 추가 행만 추가하려는 경우 다음과 같이 다시 작업 할 수 있습니다.

sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file

(이것은 줄 삽입 코드 다음에 파일의 나머지 부분을 순환하면서 첫 번째 sed 명령으로 다시 돌아 가지 않는 루프를 만듭니다).

주석에 줄이 나타나거나 들여 쓰기되거나 일치하는 패턴에 ‘^ *’를 추가 한 것을 알 수 있습니다. 100 % 완벽하지는 않지만 일반적 일 수있는 다른 상황에 적용됩니다. 필요에 따라 조정하십시오 …

이 두 가지 솔루션은 새로운 삽입 라인에 이스케이프되지 않은 백 슬래시 또는 앰퍼샌드가 포함되어 있으면 sed로 해석되고 is-와 같이 동일하게 나오지 않는 문제를 해결합니다 \n. \0일치하는 첫 번째 줄이됩니다. 특히 $ {var //}을 사용하여 먼저 모든 것을 이스케이프 해야하는 변수 또는 다른 sed 문 등을 사용하여 줄을 추가하는 경우 특히 유용합니다.

이 솔루션은 스크립트에서 조금 덜 지저분합니다 (인용 부호와 \ n은 읽기 쉽지 않습니다). 줄의 시작 부분에 a 명령에 대한 대체 텍스트를 함수에서 넣지 않으려는 경우 들여 쓰기 된 선으로. $ ‘\ n’은 셸에서 줄 바꿈으로 평가되며 정규 ‘\ n’작은 따옴표로 묶은 값이 아닙니다.

나는 perl / awk가 더 읽기 쉽기 때문에 이길 수 있다고 생각하지만 충분히 길어지고 있습니다.


답변

어쩌면 이것에 대한 답변을 게시하는 데 약간 늦었지만 위의 솔루션 중 일부는 약간 성가신 것으로 나타났습니다.

sed에서 간단한 문자열 교체를 시도했지만 작동했습니다.

sed 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file

& 기호는 일치하는 문자열을 반영한 다음 \ n과 줄 바꾸기를 추가합니다.

언급했듯이 제자리에서 수행하려면 다음을 수행하십시오.

sed -i 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file

또 다른 한가지. 표현식을 사용하여 일치시킬 수 있습니다.

sed -i 's/CLIENTSCRIPT=.*/&\nCLIENTSCRIPT2="hello"/' file

이것이 누군가를 돕기를 바랍니다.


답변

awk 변형 :

awk '1;/CLIENTSCRIPT=/{print "CLIENTSCRIPT2=\"hello\""}' file


답변

나는 비슷한 작업을했고 위의 펄 솔루션을 작동시킬 수 없었습니다.

내 해결책은 다음과 같습니다.

perl -i -pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf

설명:

정규식을 사용하여 /etc/mysql/my.cnf 파일에서 포함 된 줄만 검색 [mysqld]하고

[mysqld]
collation-server = utf8_unicode_ci

collation-server = utf8_unicode_ci포함 하는 줄 뒤에 효과적으로 줄을 추가하십시오 [mysqld].