
다음과 같은 텍스트 파일이 있습니다.
(empty)
str
int
int
s/^/\</g
이것을 현재 sed에 추가하면 (make it 's/\&/\</g;s/\</\ /g;s/^/\</g'
) 이것이 출력됩니다.
< ##only this line gets a <
str
int
int
그러나 예를 들어 새 줄을 만들고 전체 명령을 입력하면 sed -i '' 's/^/\</g' *.p*
다음과 같은 결과가 출력됩니다.
<
<str
<int
<int
차이점이 뭐야?
답변1
차이점은 입력과 출력입니다. 첫 번째 경우에는 \n
개행을 삽입했습니다. 하지만 여전히 동일한 패턴 공간에서 작업하고 있으므로 ^
패턴 공간의 헤드는 삽입된 개행이 포함되어 있더라도 제자리에 남아 있습니다. 이것이 발생할 때마다 개행을 삽입하게 됩니다 <
.
그러나 두 번째 경우에는 new를 사용 sed
하고 마지막 sed
s 출력을 입력으로 읽습니다. 따라서 모든 개행은 이제 별도의 입력 행으로 첫 번째 루프 카운트와 함께 주입되고 각 개행에는 자체 ^
패턴 공간 헤더가 있습니다.
echo ..... |
sed 's/./&\
/g;s/^/sed1/' |
sed 's/^/sed2/'
sed2sed1.
sed2.
sed2.
sed2.
sed2.
sed2
그런데...
sed 's/&/</g;s/</\
/g'
...쓰기가 더 쉬울 수도 있습니다...
sed 'y/&</\n\n/'
...하지만 각각 뒤에 줄 바꿈을 추가 [&<]
하고 각각을 바꾸려면 &
다음 <
을 수행할 수 있습니다.
sed 's/[&<]/<\
/g'
...하지만 출력이 입력과 전혀 일치하지 않습니다...
답변2
sed 'expression;expression'
동일합니까?
sed -e 'expression' -e 'expression'
그 중 여러 곳에서단순한케이스와 함께
sed -e 'expression' | sed -e 'expression'
귀하의 경우 (내가 아는 한) 모든 것을 &
로 변경 <
한 다음 <
모두 래핑하고 마지막으로 <
줄 시작 부분에 추가하려고 합니다.
s/\&/\</g;s/\</\
/g;s/^/\</g
주어진 입력을 기반으로 이 sed
스크립트는 BSD를 사용하여 다음을 수행합니다 sed
.
$ sed -f script.sed file
<
<
<
<
또는 GNU를 사용하십시오 sed
.
$ gsed -f script.sed file
<
<
str
<
int
<
int
왜 이런거야?
- 첫째,
&
파일에 아무 것도 없으므로(\
이전 것들은&
추가로 제거할 수 있음) 첫 번째 표현식은 아무 작업도 하지 않습니다. - 두 번째 표현은
\<
단어 경계(시작)와 일치합니다. 솔직히 말해서 BSD가 왜 이 텍스트를 제거했는지 조금 혼란스럽습니다sed
(이것이 OpenBSD의 버그인지 살펴보겠습니다sed
). 따라서 예제 파일의 각 단어 시작 부분에 개행 문자가 삽입됩니다. - 세 번째 표현식은 여전히 동일한(현재 수정된) 입력 라인에서 작동하며
<
라인 시작 부분에 a를 삽입합니다.
대조적으로, 단일 표현식 s/^/\</g
( \
이전 <
및 g
수정자가 필요하지 않은 경우)은 단순히 <
각 행의 시작 부분에 a를 삽입합니다.
후속 조치: sed
OpenBSD 6.1-stable 구현 시 삽입된 개행 문자로 시작하는 줄에 문자열을 추가하는 것과 관련된 버그가 확인되었습니다. 패치가 제출되었습니다.