简单搜索和替换没有正则表达式

the*_*ill 19 bash perl text

我有一个包含各种通配符的文件,我希望能够从(bash)shell脚本替换它.我有以下内容非常有用,直到其中一个变量包含对正则表达式特殊的字符:

VERSION="1.0"
perl -i -pe "s/VERSION/${VERSION}/g" txtfile.txt   # no problems here

APP_NAME="../../path/to/myapp"
perl -i -pe "s/APP_NAME/${APP_NAME}/g" txtfile.txt  # Error!
Run Code Online (Sandbox Code Playgroud)

所以相反,我想要的东西只是执行文字文本替换而不是正则表达式.是否有任何简单的单行调用perl或其他工具可以执行此操作?

Bor*_*din 18

执行此操作的"正确"方法是转义shell变量的内容,以便它们不会被视为特殊的正则表达式字符.您可以使用\ Q在Perl中执行此操作,如

s/APP_NAME/\Q${APP_NAME}/g
Run Code Online (Sandbox Code Playgroud)

但是当从shell脚本调用时,反斜杠必须加倍以避免丢失,就像这样

perl -i -pe "s/APP_NAME/\\Q${APP_NAME}/g" txtfile.txt
Run Code Online (Sandbox Code Playgroud)

但我建议用Perl编写整个脚本要容易得多


Mic*_*eyn 7

以下内容如何:

perl -i -pe "s|APP_NAME|\\Q${APP_NAME}|g" txtfile.txt
Run Code Online (Sandbox Code Playgroud)

由于垂直条不是合法角色作为路径的一部分,所以你很高兴.

  • 直到你得到`$`,`&` (2认同)
  • 在 Unix 上,“|”是有效的路径字符。事实上,除了“NUL”(“\0”)之外的所有字符在 Unix 上的文件名中都是有效的(如果不常见)。这就是为什么您应该简单地使用内置报价机制,如下鲍罗丁建议的那样。 (2认同)

Jes*_*ess 7

我不是特别喜欢这个答案,因为应该有更好的方法在 Perl 中进行文字替换。 \Q是神秘的。Usingquotemeta添加了额外的代码行。

但是...您可以substr用来替换字符串的一部分。

#!/usr/bin/perl
my $name = "Jess.*";
my $sentence = "Hi, my name is Jess.*, dude.\n";
my $new_name = "Prince//";
my $name_idx = index $sentence, $name;
if ($name_idx >= 0) {
    substr($sentence, $name_idx, length($name), $new_name);
}
print $sentence;
Run Code Online (Sandbox Code Playgroud)

输出:

#!/usr/bin/perl
my $name = "Jess.*";
my $sentence = "Hi, my name is Jess.*, dude.\n";
my $new_name = "Prince//";
my $name_idx = index $sentence, $name;
if ($name_idx >= 0) {
    substr($sentence, $name_idx, length($name), $new_name);
}
print $sentence;
Run Code Online (Sandbox Code Playgroud)

  • 你的帖子被严重低估了。谢谢先生把我从那些正则表达式中拯救出来!有时,您只需要除正则表达式之外的其他东西来替换内容(例如,在替换字符串中的正则表达式时)。 (2认同)

gle*_*man 5

您不必为此使用正则表达式(使用substr()index()length()):

perl -pe '
  foreach $var ("VERSION", "APP_NAME") {
    while (($i = index($_, $var)) != -1) {
      substr($_, $i, length($var)) = $ENV{$var};
    }
  }
'
Run Code Online (Sandbox Code Playgroud)

确保你export的变量。

  • 不需要测试我已经知道答案的东西;)当然,你的解决方案并不比简单的替换更好,至少使用 Perl ;) (2认同)