sed "e" 및 "g" 플래그가 함께 작동하지 않습니다.

sed "e" 및 "g" 플래그가 함께 작동하지 않습니다.

이것을 고려하면:

echo AAA | sed -r 's/A/echo B/ge'

알겠어요:

Becho Becho B

나는 "BBB"를 얻을 것이라고 생각했습니다. GNU sed 버전 4.2.1의 경우입니다. 무슨 일이 일어나고 있나요? 어떻게 실행 플래그를 사용하고 한 줄에서 여러 대체를 수행할 수 있습니까(펄 등이 아닌 쉘에서)?

답변1

이러한 플래그는 예상한 것과 반대되는 방식으로 함께 작동합니다. 이것문서 /e, 참고로:

이 명령을 사용하면 쉘 명령의 입력을 패턴 공간으로 파이프할 수 있습니다. 대체가 이루어지면 패턴 공간에 있는 명령이 실행되고 해당 출력이 패턴 공간을 대체합니다. 후행 줄 바꿈은 억제됩니다. 실행할 명령에 null 문자가 포함되어 있으면 결과가 정의되지 않습니다. 이것은 GNU sed 확장입니다.

글이 좀 복잡하네요. 즉, s///해당 라인에 대한 명령을 완료한 후 변경 사항이 발생하면 (새) 라인이 명령으로 실행되고 해당 출력이 해당 라인을 대체하는 데 사용됩니다.

따라서 주어진 명령에 대해:

echo AAA | sed -r 's/A/echo B/ge'

먼저 각각 Aecho B, 및그 다음에결과를 명령으로 실행합니다. 대략적으로 말하면 다음과 같은 효과가 있습니다.

echo AAA | sed -r 's/A/echo B/g' | sh

GNU는 sed원하는 모드를 직접 지원하지 않지만 원하는 경우 더 복잡한 스크립트를 사용하여 가짜로 만들 수 있습니다. 또는 명령 /e에 대한 Perl의 수정자는 s사용자가 찾고 있는 동작을 가지지만 대신 Perl 표현식을 사용합니다.

답변2

여러 대체를 가져오지만 여러 실행을 가져오지는 않습니다. 모든 교체가 완료되면 패턴이 실행됩니다.

e플래그가 없는 결과

echo AAA | sed -r 's/A/echo B/g'

echo Becho Becho B

명령줄을 실행하면 이런 일이 발생합니다하다e다음과 같은 플래그를 포함합니다 .

echo 'Becho Becho B'

답변3

GNU sed의 's' 명령과 'e' 플래그를 사용하여 'AAA'에서 'BBB'를 얻으려면 다음을 수행하십시오.

echo AAA | sed -re 's/A/echo -n B;/ge'

"AAA"는 "echo -n B;echo -n B;" echo -n B;'로 대체됩니다. 이는 실행 시 3개의 연속 echo 명령이 생성되며 각 명령은 전역 일치에 해당합니다. '-n'은 에코 출력에서 ​​개행 문자를 생략하여 'B'가 한 줄로 끝나도록 합니다(그러나 sed는 최종적으로 패턴 공간을 인쇄할 때 개행 문자 자체를 추가합니다).

답변4

무엇:

(1) 설명하는 정확한 사용 사례는 다음에서 처리할 수 있습니다.

echo AAA | sed 's/A/B/g'

(2) 실행을 위해 원하는 경우(단순한 에코보다 고급 사용을 위해) 이 e플래그를 마지막 단계로 사용할 수 있습니다.

echo AAA | sed -r 's/A/B/g;s/(.*)/echo \1/e'

(3) 무언가를 대체하는 경우에만 첫 번째 대체 명령을 실행하려면 분기를 사용하십시오.

echo AAA | sed -r 's/A/B/g;te;b;:e;s/(.*)/echo \1/e'

sed위에서 설명한 대로 이는 GNU에만 적용됩니다. BSD sed(적어도 내가 가지고 있는 버전)는 이 -r옵션을 지원하지 않으며 문자열 끝이 분기 이름 뒤에 와야 합니다. (매개변수를 사용하여 여러 옵션을 추가하면 이 마지막 문제를 해결할 수 있습니다 -e.)

주어진 입력(AAA)에 대해 이 세 개의 단일 라이너는 모두 기능적으로 동일합니다. 그러나 echo명령이 다른 것으로 변경되거나 옵션이 -n에 전달되면 sed차이점을 확인할 수 있습니다.

관련 정보