답변:
이것은 작동 bash
하고 zsh
리눅스와 OS X에서 테스트 :
sed 's/regexp/\'$'\n/g'
일반적으로 $
작은 따옴표로 묶인 문자열 리터럴 bash
은 C 스타일 백 슬래시 대체를 수행합니다 (예 : $'\t'
리터럴 탭으로 변환). 또한 sed는 개행 문자를 백 슬래시로 이스케이프 처리하기를 원하므로 \
이전 $
. 마지막으로 달러 기호 자체는 셸에서 해석되도록 따옴표로 묶지 않아야하므로 따옴표 앞에 따옴표 $
를 닫았다가 다시여십시오.
편집 : @ mklement0의 의견에서 제안했듯이 다음과 같이 작동합니다.
sed $'s/regexp/\\\n/g'
여기서 일어나는 일은 : 전체 sed 명령은 이제 C 스타일 문자열입니다. 이는 새 줄 리터럴이 다른 백 슬래시로 이스케이프되기 전에 sed가 배치되어야하는 백 슬래시를 의미합니다. 더 읽기 쉽지만이 경우 셸 문자열 대체를 수행 할 수 없습니다 (다시 작성하지 않아도 됨).
sed '\(first match\)\(second match\)/\1\'$'\n''\2/g'
입니다. \ n 뒤에 두 개의 작은 따옴표가 있습니다. 첫 번째 $
줄은 " "섹션을 닫아서 나머지 줄이 영향을받지 않도록합니다. 인용 부호가 없으면 \ 2는 무시되었습니다.
sed $'s/regexp/\\\n/g'
가독성을 향상 - 유일한주의해야 할 점은 당신이 다음 필요가있다 두배로 모든 리터럴 \
문자를.
다른 답변 중 일부가 내 버전의 sed에서 작동하지 않았습니다. 의 위치를 전환 &
하고하는 \n
일을했다.
sed 's/regexp/\n&/g'
편집 : 설치하지 않으면 OS X에서 작동하지 않는 것 같습니다 gnu-sed
.
brew install gnu-sed
다음gsed 's/regexp/\n&/g'
echo 'alias sed=gsed' >> ~/.bashrc
sed에서는 출력 스트림에 개행을 쉽게 추가 할 수 없습니다. 어색한 연속 줄을 사용해야하지만 다음과 같이 작동합니다.
$ sed 's/regexp/\
&/'
예:
$ echo foo | sed 's/.*/\
&/'
foo
자세한 내용은 여기 를 참조 하십시오 . 조금 덜 어색한 것을 원한다면 perl -pe
sed 대신 match 그룹을 사용해보십시오 .
$ echo foo | perl -pe 's/(.*)/\n$1/'
foo
$1
그룹이 괄호 안에있는 정규식에서 첫 번째 일치 그룹을 나타냅니다.
perl -pi -e 's/(.*)/\n$1/' foo
내 Mac에서 다음은 줄 바꿈 대신 단일 'n'을 삽입합니다.
sed 's/regexp/\n&/g'
이것은 개행으로 대체됩니다.
sed "s/regexp/\\`echo -e '\n\r'`/g"
sed -i '' -e ...
하고 ^M
캐럿 M (Ctrl + m)이 파일에 기록되는 데 문제가있었습니다 . 나는 같은 매개 변수로 펄을 사용했다.
\n
) 만 사용 합니다.
echo...
그리고 개행 없이 잘 작동하더라도 ) vim에서 방금 수행했습니다.
sed "s/regexp/`echo`/g"
`echo`
가 발생합니다 빈 문자열 명령 대체는 예외없이 모든 후행 뉴 라인 트림 때문에. 명령 대체를 사용하여 단일 개행을 직접 삽입 할 수있는 방법이 없습니다 ( \n\r
추가 CR을 삽입 하는 것은 끔찍한 생각입니다).
이 경우에는 sed를 사용하지 않습니다. 나는 tr을 사용한다.
cat Somefile |tr ',' '\012'
쉼표를 사용하여 캐리지 리턴으로 바꿉니다.
cat Somefile | tr ',' '\n'
YMMV
완전한 펄 정규 표현식 지원 (sed로 얻는 것보다 훨씬 강력 함) 의 장점으로 sed에서와 마찬가지로 perl one-liner를 사용할 수 있습니다 . * nix 플랫폼 간에는 변형이 거의 없습니다. perl은 일반적으로 perl입니다. 따라서 특정 시스템의 sed 버전을 원하는 방식으로 수행하는 방법에 대해 걱정하지 않아도됩니다.
이 경우에는 할 수 있습니다
perl -pe 's/(regex)/\n$1/'
-pe
sed의 정상 작동 모드와 매우 유사하게 펄을 "실행 및 인쇄"루프에 넣습니다.
'
쉘이 방해하지 않도록 다른 모든 것을 인용
()
정규 표현식을 둘러싼 그룹화 연산자입니다. $1
대치의 오른쪽에이 parens에 일치하는 것이 인쇄됩니다.
마지막으로 \n
줄 바꿈입니다.
괄호를 그룹화 연산자로 사용하는지 여부에 관계없이 일치시키려는 괄호를 피해야합니다. 따라서 위에 나열된 패턴과 일치하는 정규식은 다음과 같습니다.
\(\d\d\d\)\d\d\d-\d\d\d\d
\(
또는 \)
리터럴 패런과 \d
일치하고 숫자 와 일치합니다.
보다 나은:
\(\d{3}\)\d{3}-\d{4}
나는 중괄호 안의 숫자가 무엇을하는지 알아낼 수 있다고 생각합니다.
또한 정규 표현식에 / 이외의 구분 기호를 사용할 수 있습니다. 따라서 일치 해야하는 경우 / 탈출 할 필요가 없습니다. 아래 중 하나는 내 대답의 시작 부분에있는 정규식과 같습니다. 이론적으로 당신은 표준 /의 문자 를 대체 할 수 있습니다 .
perl -pe 's#(regex)#\n$1#'
perl -pe 's{(regex)}{\n$1}'
몇 가지 최종 생각.
사용은 -ne
대신 -pe
유사하게 작용하지만, 자동으로 마지막에 인쇄되지 않습니다. 직접 인쇄하려는 경우 편리 할 수 있습니다. 예를 들어, 여기 grep-alike가 있습니다 ( m/foobar/
정규식 일치).
perl -ne 'if (m/foobar/) {print}'
줄 바꿈 문제를 다루는 것을 발견하고 마술처럼 다루기를 원한다면을 추가하십시오 -l
. 그러나 개행 작업을 한 OP에게는 유용하지 않습니다.
보너스 팁-pcre 패키지가 설치되어 있으면 pcregrep
전체 perl 호환 정규식을 사용 하는이 함께 제공됩니다 .
리눅스에서 출력 스트림에 개행을 삽입하려면 다음을 사용했습니다.
sed -i "s/def/abc\\\ndef/" file1
어디에 file1
있었 습니까 ?
def
sed 전체 교체 전, 그리고 :
abc
def
sed 전체 교체 후. 의 사용에 유의하십시오 \\\n
. "
내부에 패턴이 있으면를 사용하여 이스케이프 처리하십시오 \"
.
sed
삽입 \n
합니다 \\n
. ---이 코드는 작동합니다 sed -i "s/def/abc\ndef/" file1
. --- GNU sed version 4.2.1
, GNU bash, version 4.1.2(1) / 4.2.25(1)
(CentOS 릴리스 6.4 / Ubuntu 12.04.3).
sed에서는 "\ 1", "\ 2"등으로 패턴의 그룹을 참조 할 수 있습니다. 따라서 찾고있는 패턴이 "PATTERN"이고 그 앞에 "BEFORE"를 삽입하려는 경우 , 당신은 산세 탈출을 사용할 수 있습니다
sed 's/(PATTERN)/BEFORE\1/g'
즉
sed 's/\(PATTERN\)/BEFORE\1/g'
-v
패턴을 제공하기 위해 awk를 사용하여이 작업을 수행 할 수도 있습니다 .
awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
라인에 주어진 패턴이 포함되어 있는지 확인합니다. 그렇다면 시작 부분에 새 줄을 추가합니다.
기본 예를 참조하십시오.
$ cat file
hello
this is some pattern and we are going ahead
bye!
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
hello
this is some
pattern and we are going ahead
bye!
한 줄의 모든 패턴에 영향을 미칩니다.
$ cat file
this pattern is some pattern and we are going ahead
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' d
this
pattern is some
pattern and we are going ahead
1
은 Awk에서 축약 형으로 사용됩니다 {print $0}
. 그 이유는 True로 평가되는 모든 조건이 현재 레코드 인쇄로 구성된 Awk의 기본 동작을 트리거하기 때문입니다.
이 질문에 대한 모든 답을 읽은 후에도 여전히 다음 예제 스크립트에 올바른 구문을 얻으려고 많은 시도가 필요했습니다.
#!/bin/bash
# script: add_domain
# using fixed values instead of command line parameters $1, $2
# to show typical variable values in this example
ipaddr="127.0.0.1"
domain="example.com"
# no need to escape $ipaddr and $domain values if we use separate quotes.
sudo sed -i '$a \\n'"$ipaddr www.$domain $domain" /etc/hosts
스크립트는 \n
단일 sed
명령을 사용하여 파일 끝에 줄 바꿈 과 다른 텍스트 줄을 추가합니다 .
sed '/regex/G'