1

我在使用更改名为“.backup.conf”的配置文件的shell脚本时遇到了一些问题。

配置文件如下所示:

inputdirs=(/etc /etc/apm /usr/local)
outputdir="test_outputdir"
backupmethod="test_outputmethod"
loglocation="test_loglocation"`

我的脚本需要更改配置文件变量之一,而最后 3 个变量我没有遇到任何问题。

如果我想将变量“inputdirs”/etc/ 更改为 /etc/perl,我应该使用什么表达式?

如果我使用带有附加的回声,它只会将其附加到文件的末尾。

我尝试使用以下格式的 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 ,变量 inputdirs 最终应该看起来像inputdirs=(/etc/perl /etc/apm /usr/local)

谢谢您的帮助!

4

2 回答 2

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. 我们创建一个新变量 decrementing $izbor
  3. 这是实际的替代表达式。我将分部分解释:
    1. 首先我们匹配括号字符[(]
    2. 我们现在将搜索一系列非空格,后跟一个空格 ( [^ ]*)。
    3. 此搜索(通过内括号中的分组标识)重复$izbor1多次 ( {$izbor1})
    4. 前面的表达式被分组到一个外括号组中,以便被捕获到一个辅助变量\1中。
    5. 我们现在匹配我们想要替换的单词。它由不是空格且不是右括号的字符序列组成(这是为了处理最后一个单词的情况)
    6. 替换由捕获的 value 形成\1,然后是我们的新字符串。

希望这会有所帮助=)

于 2012-10-19T17:32:14.513 回答
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和括号内的空格并且不处理制表符,但它应该适合你。此外,有些sed允许[^ ][^ ]*更简单地写为[^ ]+,但这并不普遍。

于 2012-10-19T17:46:45.893 回答