我想编写一个修改.properties文件中变量的脚本。用户输入新值,然后将其写入文件。
read -p "Input Variable?" newVar
sed -r 's/^\s*myvar=.*/myvar=${newVar}/' ./config.properties
不幸的是,当用户输入特殊字符时会出现问题。在我的用例中,很可能输入“/”字符。所以我的猜测是我必须为所有斜杠解析$ {newVar}并逃脱它们?但是怎么样?还有更好的方法吗?
答案 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