2020년 5월 26일 업데이트됨
이것이 버그인 것 같아서 버그를 신고했습니다. ID는 #41558입니다.
나는 단지 장난을 치고 있었고 sed
다음 연습을 생각해 냈습니다. "and"(하위 문자열이 아닌 단어)의 마지막에서 세 번째 항목을 교체하여 생성합니다.
dog XYZ foo and bar and baz land good
난 이게 효과가 있을 거라고 생각했어
echo 'dog and foo and bar and baz land good' |
sed -E 's/(.*)\band\b((.*\band\b){2})/\1XYZ\2/'
그러나 실제로는 "and"의 끝에서 두 번째 발생을 대체합니다. 내가 생각할 수 있는 유일한 설명은 그 중 하나에 "토지"가 포함되어 있다는 것인데 , "경계"라는 단어를 \band\b
포함시켰으니 그래야 하지 않을까 ?\b
답변1
sed
이는 PCRE에서 지원되는 것처럼 둘러보기 등이 지원되지 않기 때문에 수행하기 어렵습니다 . 문자열을 거꾸로 하고 처음부터 세 번째로 나오는 반전된 단어를 바꾼 다음 다시 바꾸는 것이 더 쉬울 것입니다.
$ echo 'dog and foo and bar and baz land good' | rev | sed 's/\<dna\>/XXX/3' | rev
dog XXX foo and bar and baz land good
표현이 작동하지 않는 이유는 버그처럼 보입니다. 역참조는 마치 이전 내용이 전혀 영향을 미치지 않은 것처럼 \3
string 인 것으로 보입니다 . baz land
\b
and
.*\band\b
주문하다
sed -E 's/(.*)\<and\>((.*\<and\>){2})/\1XYZ\2/'
sed
OpenBSD에서 기본으로 올바른 작업을 수행 하는 것 같습니다(사용 \<
및 \>
교체 ).\b
sed
나는 GNU 또는 GNU에 대한 기존 버그 보고서를 찾지 못했습니다 glibc
. 적어도 그것이라도 놀라지 않을 것입니다.관련된도착하다glibc 오류 25322(왜냐하면 아래를 참조하세요).
이 문제를 더 자세히 해결할 수 있습니다.
sed -E 's/(.*)\band\b(.*\band\b.*\band\b)/\1XYZ\2/'
답변2
질문을 하는 것이 좋습니다. 예제를 테스트한 결과 GNU grep
, GNU sed
동일한 동작이 발생합니다 GNU awk
. 아래에 언급된 한 가지 경우를 제외하고.
잘못된 출력:
$ echo 'cocoa' | sed -nE '/(\bco){2}/p' cocoa
sed -nE '/(\<co){2}/p'
또한awk '/(\<co){2}/'
잘못된 동작이 있지만grep -E '(\<co){2}'
올바르게 출력이 제공되지 않습니다.동작이 정확하고 출력이 없습니다.
$ echo 'cocoa' | sed -nE '/\bco\bco/p'
it
출력 오류: 완전한 단어가 1개만 나옵니다.with
$ echo 'it line with it here sit too' | sed -E 's/with(.*\bit\b){2}/XYZ/' it line XYZ too
동작이 정확하며 입력이 수정되지 않았습니다.
$ echo 'it line with it here sit too' | sed -E 's/with.*\bit\b.*\bit\b/XYZ/' it line with it here sit too
단어 경계를 변경하면
\<
다른\>
문제가 발생합니다.이게 맞다수정하지 마세요입력하다:
$ echo 'it line with it here sit too' | sed -E 's/with(.*\<it\>){2}/XYZ/' it line with it here sit too
이것은 입력을 올바르게 수정합니다.
$ echo 'it line with it here it too' | sed -E 's/with(.*\<it\>){2}/XYZ/' it line XYZ too
하지만 입력을 수정할 수는 없습니다.
$ echo 'it line with it here it too sit' | sed -E 's/with(.*\<it\>){2}/XYZ/' it line with it here it too sit
또한 문제가 있는 동작은 충돌하는 단어의 시작 부분에 추가 문자가 있는 경우에만 발생합니다. 예를 들어, it
및 sit
. 하지만 끝에 문자가 있는 경우에는 그렇지 않습니다. 예를 들어, it
및 site
.item
$ echo 'it line with it here item too' | sed -E 's/with(.*\bit\b){2}/XYZ/'
it line with it here item too
$ echo 'it line with it here it too item' | sed -E 's/with(.*\<it\>){2}/XYZ/'
it line XYZ too item