如何更改模板中替换变量的格式

时间:2008-10-27 20:51:06

标签: unix sed text-files

我需要遍历目录中的文件并执行以下替换。

之前:

  

Hello $ {USER_NAME},您住在哪里   $ {} HOME_ADDRESS。它现在是$ {TIME}

后:

  

Hello $ {userName},你住在哪里   $ {}是homeAddress。现在是$ {time}

$ {}中出现的不同令牌数量很大,因此运行起来并不可行:

find . -name '*' -exec sed -i 's/${USER_NAME}/${userName}/g' {} \;
find . -name '*' -exec sed -i 's/${TIME}/${time}/g' {} \;

我希望可以使用单个命令执行此替换,看起来像:

find . -name '*' -exec sed 's/XXX/YYY/g' {} \;

但我无法弄清楚替换XXX和YYY的原因。是否可以在一个命令中执行此操作?

干杯, 敦尔

3 个答案:

答案 0 :(得分:4)

为清晰起见而格式化:

sed -i '/^Hello/ { s/\$\{USER_NAME\}/\$\{userName\}/g 
                   s/\$\{HOME_ADDRESS\}/\$\{homeAddress\}/g 
                   s/\$\{TIME\}/\$\{time\}/g
                  }'

/^Hello/标识您希望采取行动的行(如果需要,使其更具体),其余部分替换每个变量名称。


如果将其写入脚本,请考虑使用HERE文档来保持格式化并使其更易于阅读和更新...

答案 1 :(得分:2)

sed的-i标志将就地编辑文件。对于XXX和YYY,您可以使用以下内容:

sed -i 's/USER_NAME/userName/g'

等等。

更新:我发现您的问题实际上是自动将“USER_NAME”更改为“userName”。你可以尝试这个Perl脚本:

sub convert {
    my $r = lc $_[0];
    $r =~ s/_(.)/\U$1\E/g;
    return $r;
}
while (<>) {
    s/\${([A-Z_]+)}/\${@{[convert $1]}}/g;
    print;
}

像这样运行:

perl -i convert.pl inputfile.txt

示例输出:

$ cat inputfile.txt
Hello ${USER_NAME}, you live at ${HOME_ADDRESS}. It is now ${TIME}
$ perl -i convert.pl inputfile.txt
$ cat inputfile.txt
Hello ${userName}, you live at ${homeAddress}. It is now ${time}

答案 2 :(得分:0)

上面的答案非常有效。为了完整起见,我可以补充一点:

sed '/^Hello/ { s/\$\{USER_NAME\}/\$\{userName\}/g' <filename> \
   | sed 's/\$\{HOME_ADDRESS\}/\$\{homeAddress\}/g' \
   | sed 's/\$\{TIME\}/\$\{time\}/g'

它们在功能上是相同的(除了我的转储到stdout;你必须把它放在某个地方(但你要保留原件以防万一,就像e,你经常搞乱你的regexp)。我喜欢我的配方只是因为我可以从一个sed命令开始,然后使用

添加更多
!! | sed 'yet-enother-regexp'

箭头键? VI-模式?谁需要那些东西? :)