목표에 매우 가까워졌지만 지금은 막혔습니다.
phpmyadmin
구성 파일을 간단하게 편집하기 위해 자동화된 스크립트를 작성하려고 합니다 .
cat /usr/share/phpmyadmin/config.sample.inc.php |sed s^//\ \$cfg\\[\'Servers\'^\$cfg\\[\'Servers\'^
//
기본적으로 . 로 시작하는 모든 줄을 제거하려고 합니다 // $cfg['Servers']
. 위의 줄은 트릭을 수행하지만 내가 해야 할 모든 탈출 작업에 만족하지 않습니다. 나는 이 sed 명령의 수백 가지 변형을 시도했지만 다른 모든 문자를 이스케이프하는 것이 지금까지 작동하는 유일한 방법인 것 같습니다.
sudo sh -c
또 다른 장애물: 궁극적으로 위의 명령 문자열을 상승된 셸( 사용)을 통해 전달하고 싶습니다. 예를 들면 다음과 같습니다.
sudo sh -c "cat /usr/share/phpmyadmin/config.sample.inc.php |sed s^//\ \$cfg\\[\'Servers\'^\$cfg\\[\'Servers\'^ >/usr/share/phpmyadmin/config.inc.php"
하지만 이 작업을 시도할 때마다 다음 오류가 발생합니다.
sed: -e expression #1, char 27: unterminated `s' command
그래서 제 질문은 다음과 같습니다. sed
너무 많은 문자를 이스케이프 처리할 필요가 없도록 표현을 단순화할 수 있습니까? 명령을 위반하지 않도록 어떻게 표현을 상승된 셸에 전달할 수 있습니까 sed
s
?
내 주요 문제는 상승된 쉘에 큰따옴표로 구분된 문자열이 전달되고 sed 문자열에 작은따옴표가 포함되어 있다는 것입니다. 과거에는 일반적으로 두 가지를 모두 사용하는 명령이 없었기 때문에 하나를 다른 것으로 대체할 수 있었습니다.
답변1
스크립트를 큰따옴표로 올바르게 묶으면 공백과 작은따옴표를 이스케이프할 필요가 없습니다.
sed "s^// \$cfg\['Servers'^\$cfg['Servers'^" file
또한 대체 항목의 대괄호를 이스케이프할 필요가 없습니다. 정규식의 괄호는 이스케이프 처리해야 합니다. 그렇지 않으면 특수 정규식 기호로 이해되기 때문입니다.
이스케이프를 최소화하기 위한 가장 좋은 방법은 sed 명령을 파일에 넣어 큰따옴표가 필요하지 않고 $
쉘 확장에서 대체할 때 달러 기호를 보호할 필요가 없도록 하는 것입니다.
servers.sed
:
s^// \$cfg\['Servers'^$cfg['Servers'^
그런 다음 다음과 같이 실행하십시오.
sed -f servers.sed file
마지막 형식은 상승된 셸에서도 사용하기 쉽습니다.
sudo sh -c 'sed -f servers.sed file > newfile'
답변2
문제를 단순화하는 데 도움이 될 수 있는 몇 가지 관찰 사항은 다음과 같습니다.
파일을 생성 cat
한 다음 렌더링할 sed
필요 가 없습니다 stdin
. 파일 이름을 얻거나 sed
매개변수 목록에서 <
연산자를 사용하는 것도 가능합니다.
명령줄에서 인용 문자를 사용자의 책임으로 보지 마십시오. shell
명령을 따옴표로 묶으면 작동합니다.
이제 명령에 작은따옴표가 이미 있으므로 sed
큰따옴표를 사용하는 것이 쉽습니다 .
$
하지만 그런 다음에는 큰따옴표 안에 해석된 문자를 꺼야 합니다shell
.- 대괄호는
[
리터럴로 해석될 것으로 예상하여 인용해야 합니다sed
.
이것으로 shell
문제가 해결됩니다. sed
이제 명령을 살펴보겠습니다.
여기서 불필요하게 교체 부품을 반복하고 있습니다. 목표는 단지 앞에 있는 이중 슬래시를 제거하는 것이므로 명령 /selectline/s/pat/repl/
형식을 사용해야 합니다 s///
.
해당 줄이 이미 선택되어 있으므로 처음 3개의 문자(// 및 공백)가 무엇인지 알 수 있습니다.
이 명령에는 미묘한 오류가 숨어 있습니다 sed
. 대체 명령 구분 기호로 사용하기로 선택했으므로 ^
더 이상 첫 번째 줄 문자로 사용되지 않습니다.
용어 상 regex
이는 줄의 어느 위치에서나 이중 슬래시가 변경될 수 있음을 의미합니다. 분명히 그것은 귀하의 사양이 말하는 것이 아닙니다. 그래서 우리는 다른 구분 기호를 사용합니다.|
base=/usr/share/phpmyadmin
if=$base/config.sample.inc.php
of=$base/config.inc.php
< "$if" \
sed -e "\\|^// \$cfg\\['Servers']|s/...//" \
> "$of"
sed 명령줄에서 작은따옴표를 사용하여 백슬래시 로드를 약간 줄일 수도 있습니다.
sed -e '\|^// $cfg\['\''Servers'\'']|s/...//'
이제 sudo
부분으로 넘어갑니다. sed
명령을 shell
문자열로 인터프리터 에 전달합니다 . 대신, shell's stdin
heredoc 연산자를 통해 명령을 전달할 수 있습니다 <<
.
sudo sh <<\eof
base=/usr/share/phpmyadmin
if=$base/config.sample.inc.php
of=$base/config.inc.php
< "$if" sed -e "\\|^// \$cfg\\['Servers']|s/...//" > "$of"
eof
화타이
PS 터미널에서 멀리 떨어져 있어서 아직 테스트해 보지 못했습니다.