我一直在使用shell脚本遇到一些问题,这个脚本会更改名为“.backup.conf”的配置文件。
配置文件如下所示:
inputdirs=(/etc /etc/apm /usr/local)
outputdir="test_outputdir"
backupmethod="test_outputmethod"
loglocation="test_loglocation"`
我的脚本需要更改其中一个配置文件变量,并且我对最后3个变量没有任何问题。
如果我想将变量“inputdirs”/ etc /更改为/ etc / perl,我应该使用什么表达式?
如果我使用echo with append,它只会将它附加到文件的末尾。
我尝试过使用以下格式的sed:
sed -i 's/${inputdirs[$((izbor-1))]}/$novi/g' .backup.conf
其中“izbor”是我想要从inputdirs更改的变量,而“novi”是新路径(例如/ etc / perl)。
因此,使用以下配置文件以及变量$izbor=1
和$novi=/etc/perl
,我应该将第一个变量inputdirs=/etc
更改为/etc/perl
变量inputdir应该最终看起来像inputdirs=(/etc/perl /etc/apm /usr/local)
感谢您的帮助!
答案 0 :(得分:2)
你可以试试这个:
enovi="$(printf '%s\n' "$novi" | sed -e 's/[\\&/]/\\&/g')"
izbor1="$(expr "$izbor" - 1)"
sed -rie "s/([(]([^ ]* ){$izbor1})[^ )]*/\\1$enovi/" config.txt
命令摘要:
$enovi
,其转义内容为$novi
。基本上,转义了以下字符:&
,\
和/
。因此/etc/perl
变为\/etc\/perl
。$izbor
。[(]
。[^ ]*
)。$izbor1
次({$izbor1}
)\1
中。\1
形成的,后跟我们的新字符串。希望这有助于=)
答案 1 :(得分:1)
如果您尝试使用$ izbor作为索引,它可能希望成为s///
的标志。假设您的输入与^inputdirs=(
匹配(没有空格),您可以放弃:
sed -i '/^inputdirs=(/{
s/(/( /; s/)/ )/; # Insert spaces inside parentheses
s@ [^ ][^ ]* @ '"$novi@$izbor"';
s/( /(/; s/ )/)/; } # Remove inserted spaces
' .backup.conf
前两个表达式确保括号内有空格, 如果你的输入已经有空格,那么可能没有必要。它在上面有点混淆,但基本上你正在做的替换是这样的:
s@ [^ ][^ ]* @/etc/perl@2
其中2
标志告诉sed仅替换第二次出现的匹配。这真的很脆弱,因为它在inputdirs
之前不需要空格,并且在parens内部没有空白并且不处理制表符,但它应该适合你。此外,有些sed
允许[^ ][^ ]*
更简单地写为[^ ]+
,但这不是通用的。