3

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

前:

您好 ${USER_NAME},您住在 ${HOME_ADDRESS}。现在是 ${TIME}

后:

您好 ${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。是否可以在单个命令中执行此操作?

干杯,多纳尔

4

3 回答 3

4

为清晰起见格式化:

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

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


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

于 2008-10-27T21:05:09.477 回答
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}
于 2008-10-27T20:57:02.813 回答
0

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

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

它们在功能上是相同的(除了我的转储到标准输出;你必须把它放在某个地方(但你必须保留原件,以防你经常弄乱你的正则表达式)。我喜欢我的公式只是因为我可以从一个 sed 命令开始,然后添加更多

!! | sed 'yet-enother-regexp'

方向键?vi模式?谁需要那些东西?:)

于 2008-10-27T21:12:29.787 回答