从regexp(sed)参数中转义保留字符

时间:2011-07-04 14:02:49

标签: regex sed escaping

我想编写一个修改.properties文件中变量的脚本。用户输入新值,然后将其写入文件。

read -p "Input Variable?" newVar
sed -r 's/^\s*myvar=.*/myvar=${newVar}/' ./config.properties

不幸的是,当用户输入特殊字符时会出现问题。在我的用例中,很可能输入“/”字符。所以我的猜测是我必须为所有斜杠解析$ {newVar}并逃脱它们?但是怎么样?还有更好的方法吗?

4 个答案:

答案 0 :(得分:3)

看一下bash printf

%q  quote the argument in a way that can be reused as shell input

示例:

$ printf "%q" "input with special characters // \\ / \ $ # @"
input\ with\ special\ characters\ //\ \\\ /\ \\\ \$\ #\ @

答案 1 :(得分:1)

避免引用shell是一个很好的一般原则。

#! /usr/bin/env perl

use strict;
use warnings;

die "Usage: $0 properties-file ..\n" unless @ARGV;

print "New value for myvar?\n";
chomp(my $new = <STDIN>);

$^I = ".bak";
while (<>) {
  s/^(\s*myvar\s*=\s*).*$/$1$new/;
  print;
}

s///用户来说,sed替换为-i

上面的代码使用Perl的就地编辑工具(最常用$^I开关启用但在上面使用特殊的.bak变量)来修改命令行上命名的文件并使用{{1}}扩展名。

使用示例:

$ cat foo.properties 
theirvar=123
myvar=FIXME

$ ./prog foo.properties 
New value for myvar?
foo\bar

$ cat foo.properties
theirvar=123
myvar=foo\bar

$ cat foo.properties.bak 
theirvar=123
myvar=FIXME

答案 2 :(得分:0)

编辑:oops,我们只是要求值,而不是正则表达式。所以这就是你需要的

如果可用,最好使用perl代替sed

read -p "Input Variable?" newVar
perl -i -p -e 'BEGIN{$val=shift;}'           \
           -e 's/^\s*myvar=.*/myvar=$val/'   \
           "$newVar" ./config.properties

Edit2:抱歉,仍然没有处理newVar中的\字符。猜猜其他解决方案之一更好。如前所述,处理shell转义是你的问题。

答案 3 :(得分:0)

你最好使用一个理解变量的工具 - Perl,也许是AWK - 尝试引用一个随机字符串,这样你就可以避免所有与sed命令解析的意外交互都会遇到麻烦。

此外,使用单引号时不会插入变量,即使使用-r,sed也不会使用Perl正则表达式语法 - -r只能转到egrep }版本的正则表达式,所以\s没有做你想要的。

无论如何,忽略了我自己的建议,这就是我们在拥有这些更好的工具之前的过去:

read -p "Input Variable?" newVar
sed "/^ *myvar=/c\\
myvar=`echo \"$newVar\" | sed 's/\\\\/\\\\\\\\/'`" ./config.properties

如果您认为您的用户不会想出如何在提示符下输入文字反斜杠,可以将其简化为:

read -p "Input Variable?" newVar
sed "/^ *myvar=/c\\
myvar=$newVar" ./config.properties