Bash - 使用sed更改配置文件

时间:2012-10-19 16:54:17

标签: linux bash shell configuration

我一直在使用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)

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

你可以试试这个:

enovi="$(printf '%s\n' "$novi" | sed -e 's/[\\&/]/\\&/g')"
izbor1="$(expr "$izbor" - 1)"
sed -rie "s/([(]([^ ]* ){$izbor1})[^ )]*/\\1$enovi/" config.txt

命令摘要:

  1. 第一行生成一个变量$enovi,其转义内容为$novi。基本上,转义了以下字符:&\/。因此/etc/perl变为\/etc\/perl
  2. 我们创建一个新的变量递减$izbor
  3. 这是实际的替代表达式。我会解释一下:
    1. 首先,我们匹配括号字符[(]
    2. 我们现在将搜索一系列非空格,后跟一个空格([^ ]*)。
    3. 此搜索(通过内括号中的分组确定)重复$izbor1次({$izbor1}
    4. 先前的表达式被分组到外括号组中,以便被捕获到辅助变量\1中。
    5. 我们现在匹配我们要替换的单词。它由一系列不是空格的字符组成,不是右括号(这是为了处理最后一个单词的情况)
    6. 替换是由捕获的值\1形成的,后跟我们的新字符串。
  4. 希望这有助于=)

答案 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允许[^ ][^ ]*更简单地写为[^ ]+,但这不是通用的。