내 스크립트에 이와 비슷한 코드가 있습니다 ...
smbconffile="/etc/samba/smb.conf"
sed -i 's/.*[\[CMI\]]/\[CMI\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[LOCAL\]]/\[LOCAL\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[NATIONAL\]]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || "Failed"
이렇게 하면 samba conf(smb.conf)의 공유 이름이 CMI$, LOCAL$, NATIONAL$로 변경됩니다.
내가 가진 문제는 두 번째 sed 명령 후에 sed가 "NATIONAL"을 찾았지만 "NATIONAL$" 대신 "LOCAL$"로 이름을 바꾼다는 것입니다. 명령에 문제가 있는 사람이 있나요? 어떤 도움이라도 대단히 감사하겠습니다.
답변1
문자 클래스(대괄호 안의 문자 목록)를 대괄호 리터럴로 묶은 smb.conf 공유 이름과 혼합합니다. 또한 명령의 형식이 잘못되었습니다. echo
쉘은 0이 아닌 상태로 종료하지 않고 명령을 호출하려고 시도합니다.sed
Failed
몇 가지 조언:
- 문자 클래스 제거(외부 괄호)
- 선행을 제거하면
.*
선행 주석 등이 제거됩니다. sed
여러 문이 포함된 단일 명령 실행- 오류 상태 메시지 수정
sed -i 's/\[CMI\]/\[CMI\$\]/;
s/\[LOCAL\]/\[LOCAL\$\]/;
s/\[NATIONAL\]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || echo "Failed"`
역참조를 사용하면 대체 표현식에서 원래 접두사(예: "[CMI")를 다시 입력하지 않아도 되지만 이렇게 하면 표현식을 읽기가 더 어려워집니다.
또 다른 제안은 읽기 가능한 그룹화 및 역참조(IMO)가 있는 Perl을 사용하는 것입니다.
perl -pi -e 's/(\[(?:CMI|LOCAL|NATIONAL))\]/$1\$]/g' $smbconffile \
&& echo "Success" || echo "Failed"
편집하다:[
명확히 하자면, 외부 괄호가 있는 원래 표현식의 문제점은 (첫 번째 경우) , C
, M
, I
) ]
다음에 임의의 순서로 가 포함된 문자열과 동일한 문자 클래스를 생성한다는 것입니다 ]
.
$ echo '[IMC]' | sed 's/[\[CMI\]]/[something_else]/'
[IM[something_else]
$ echo '[FOOM]' | sed 's/[\[CMI\]]/[something_else]/'
[FOO[something_else]
외부 대괄호를 제거하면 문자 클래스가 제거되므로 표현식은 제공된 부분 문자열과 정확히 일치합니다.