클라이언트 시스템을 복제하고 파일의 특정 줄을 변경하는 스크립트를 작성 중입니다.
다음 줄이 포함된 소스 파일이 있습니다.
$DB_HOST = "LegitDbHost";
대상 파일에는 다음 줄이 있습니다.
$DB_HOST = "testDbHost";
따라서 타겟 라인을 소스 라인으로 교체해야 하며 다음과 같은 내용을 인쇄하고 싶습니다.
Replacing line 12: '$DB_HOST = "testDbHost";' ==with==> '$DB_HOST = "LegitDbHost";'(y/n):
지금까지 나는 이것을 얻었습니다 :
toReplace='$DB_HOST';
sourceLine=$(cat ./sourceFile.php | grep -m 1 "$toReplace[[:space:],=]");
destLineNr=$(cat ./destFile.php | grep -n -m 1 "$toReplace[[:space:],=]" | grep -Eo '^[^:]+');
destLine=$(cat ./destFile.php | grep -m 1 "$toReplace[[:space:],=]");
read -p "Replacing line $destLineNr: $destLine ==with==> $sourceLine.(y/n): ";
그러나 내 출력은 다음과 같습니다.
==with==> $DB_HOST ST = "testDbHost";.(y/n):
;
이는 sourceLine이 내부를 갖고 있고 Command 측으로 해석되기 때문이라고 생각합니다 . 이 문제를 해결하는 방법을 모르겠습니다.
이것이 이해할 수 있기를 바랍니다.
편집하다:
제안한대로 나는echo -n
toReplace='$DB_HOST';
sourceLine=$(cat ./sourceFile.php | grep -m 1 "$toReplace[[:space:],=]");
destLineNr=$(cat ./destFile.php | grep -n -m 1 "$toReplace[[:space:],=]" | grep -Eo '^[^:]+');
destLine=$(cat ./destFile.php | grep -m 1 "$toReplace[[:space:],=]");
echo -n "Replacing line $destLineNr: "
echo -n $destLine
echo -n " ===with===> "
echo -n $sourceLine
이것은 다음과 같이 인쇄됩니다:
===with===> $DB_HOST = "testDbHost";OS";
답변1
노력하다:
#! /bin/zsh -
die() {
print -ru2 -- "$@"
exit 1
}
srcFile=./sourceFile.php
dstFile=./destFile.php
toReplace='$DB_HOST'
sourceLine=$(<"$srcFile" grep -Pm1 "\Q$toReplace\E[\s,=]") ||
die "Can't find $toReplace in $srcFile"
<"$dstFile" grep -nPm 1 "\Q$toReplace\W[\s,=]" |
IFS=: read -r destLineNr destLine ||
die "Can't find $toReplace in $dstFile"
if
read -q "?Replacing line $destLineNr: ${(q+)destLine} ==with==> ${(q+)sourceLine}? (y/n): "
then
(
export destLineNr destLine
perl -lpi -e '$_ = $ENV{destLine} if $. == $ENV{destLineNr}' -- "$dstFile"
)
fi
zsh 매개변수 확장을 사용하면 ${(q+)line}
해당 변수의 CR 문자(입력 파일에 Unix LF 구분 기호 대신 MSDOS CRLF 구분 기호가 있는 것처럼 보이므로)가 C-M
터미널에 있는 그대로 전송되는 대신 렌더링됩니다(터미널의 경우 CR 문자는 커서를 줄의 시작 부분으로 되돌립니다(텔레타이프 기계의 캐리지 리턴).