GNU sed가 "e" 수정자로 실행된 명령에 일치하지 않는 줄 내용을 추가하는 이유는 무엇입니까?

GNU sed가 "e" 수정자로 실행된 명령에 일치하지 않는 줄 내용을 추가하는 이유는 무엇입니까?

다음 명령은 텍스트 사용자 이름과 그룹 이름을 UID 및 GID로 올바르게 바꿉니다.

echo "uidNumber=root" | sed -E 's/((u|g)idNumber=)([^,+]+)/echo -n \1; id -\2 \3/eg'
uidNumber=0

그러나 패턴과 일치하는 텍스트 앞에 텍스트를 추가하면 대체 명령이 실행되기 전에 추가되어 오류가 발생합니다.

echo "anotherAttr,uidNumber=root" | sed -E 's/((u|g)idNumber=)([^,+]+)/echo -n \1; id -\2 \3/eg'
h: line 1: anotherAttr,echo: command not found
0

패턴과 일치하는 텍스트 뒤에 텍스트를 추가하면 동일한 일이 발생하는 것 같습니다. 이 경우 텍스트가 추가됩니다.

echo "anotherAttr1,uidNumber=root,anotherAttr2" | sed -E 's/((u|g)idNumber=)([^,+]+)/echo -n \1; id -\2 \3/eg'
sh: line 1: anotherAttr1,echo: command not found
id: ‘root,anotherAttr2’: no such user

실행된 명령 앞에 일치하지 않는 텍스트가 추가되는 이유는 무엇이며, 이러한 일이 발생하지 않도록 하려면 어떻게 해야 합니까?

편집: 다른 사용자는 전체 라인 일치를 제안했지만 이로 인해 g수정자가 제대로 작동하지 않으며 허용되는 솔루션이 아닙니다.

답변1

이 문제는 수정자의 작동 방식에 대한 근본적인 오해로 인해 발생합니다 e.

교체는 s한 번만 적용하거나 패턴 버퍼 전체( 의 경우 g)에 적용할 수 있습니다. e패턴 버퍼의 내용은 교체를 수행한 후 실행됩니다.

수정은 매우 간단합니다. 달러와 슬래시를 피하고, echo -n "패턴 버퍼에 추가하고, "패턴 버퍼에 추가하고, 각 대체 명령을 모두 서브쉘 확장에 넣습니다.

p실행될 내용을 보여줌으로써 디버깅을 돕기 위해 추가되었습니다 .

echo "anotherAttr1,uidNumber=root,gidNumber=root,anotherAttr2" | sed -E 's/\\/\\\\/g;s/\$/\\$/g;s/^/echo "/;s/$/"/;s/((u|g)idNumber=)([^,+]+)/\1$(id -\2 \3)/peg'
echo "anotherAttr1,uidNumber=$(id -u root),gidNumber=$(id -g root),anotherAttr2"
anotherAttr1,uidNumber=0,gidNumber=0,anotherAttr2

관련 정보