如何不将字符串解释为命令

如何不将字符串解释为命令

我正在编写一个脚本,该脚本应该复制客户端系统并更改文件中的某些行。

有一个源文件,其中有一行:

$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 有一个;内部并且被解释为命令端。我只是不知道如何解决这个问题。

我希望这是可以理解的。

编辑: 按照建议我尝试使用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

使用${(q+)line}zsh 参数扩展,将确保该变量中的 CR 字符(因为它看起来像您的输入文件具有 MSDOS CRLF 分隔符而不是 Unix LF 分隔符)呈现为而C-M不是按原样发送到终端(对于终端,a CR 字符使光标返回到行的开头(对于电传打字机来说是回车))。

相关内容