如何在Perl中用另一组单词替换文件中的一组单词?

3
我的要求是用第二个词组替换给定文本文件中的一组单词,这些单词可能来自命令行或另一个文件。由于我的代码也是用Perl编写的,所以希望使用Perl来完成这项任务。
因此,如果我有以下内容:
server name="${server1}" host="abc.com"
server name="${server2}" host="webcs.com"
server name="${server5}" host="httpvcs1.com"
server name="${server6}" host="xyz.com"
server name="${server7}" host="msg.com"

我希望用不同的词汇替换'server1'、'server2'、'server5'等字符串。这些词汇可以放在另一个文件中或从命令行中给出(哪种方法更可行)。
此外,如果我想将“server”一词替换为“file”,那么如何制作一个正则表达式来进行替换?
perl -pie 's/server\d{1-3}/myword/g' loginOut.txt > loginOut1.txt

上述代码将替换所有包含“myword”的单词。但我只想替换子字符串。

这里似乎没有问题 - 你似乎已经回答了自己的问题。 - George Stocker
@Gortok:我希望替换一个子字符串,但我的查询会替换整个单词。 - gagneet
我不清楚您想要替换字符串的哪个部分... - Ape-inago
我希望将“server1”、“server2”、“server5”等替换为类似“file1”、“file2”、“file5”等的内容。 - gagneet
6个回答

2

你的第二个问题的正则表达式应该是s/server/myword/g;。它匹配(并替换)任何出现的"server"。

要用不同的字符串替换server1,server2等,你可以有一个包含替换规则的文本文件,例如:

server1 abcd
server2 bcde
server3 cdef
etc.

您可以从文件中读取日期,并将其存储在哈希表中,例如:

my %dict;
while(<DICTFILE>){
    /(\S+)\s+(\S+)/;
    $dict{$1}={$2};
}

然后进行替换:
while(my $line = <>){
    foreach my $s (keys %dict){
        $line =~ s/$s/$dict{$s}/g;
    }
    print $line;
}

你的字典构建缺少搜索的闭合/。my %dict; while(){ /(\S+)\s+(\S+); $dict{$1}={$2}; } - Hudson
你把值写回原文件的哪里了? 我希望用这组值改变原文件。 - gagneet
当$s包含正则表达式特殊字符(例如. [] {} \ *?+)时,这将会出错。 - Tomalak
这还不错。对于原地替换,您可以使用Tie::File将文件绑定到数组。 - Svante
我必须删除赋值语句右侧的括号才能使其正常工作:$dict{$1}=$2; - krookedking

1

您只需要根据自己的情况取所需,使其独特即可。

在这种情况下,您可以执行以下操作:

s/{server/{file/g;


1
以上所有答案都有一些缺陷。您要求某种方法来替换'server1','server2','server5'等内容,以类似于'file1','file2','file5'等内容。
该命令为(在Windows提示符中为-pe,而不是-pie):
perl -pe "s/\{server/\{file/g" in.txt > out.txt

而 out.txt 是:

server name="${file1}" host="abc.com"
server name="${file2}" host="webcs.com"
server name="${file5}" host="httpvcs1.com"
server name="${file6}" host="xyz.com"
server name="${file7}" host="msg.com"

根据你最新的评论,我相信这正是你想要的。


0

将您的正则表达式更改为以下内容:

perl -pie 's/\{server/myword/g' loginOut.txt > loginOut1.txt

它还保留了开头的$和结尾的},因此"foo=${server1}"将变成"foo=$myword1}"。 - Hudson
-i选项不会重写输入文件,那么在这种情况下loginOut1.txt会变为空吗? - Adrian Pronk

0

您可能想尝试使用Template Toolkit


以下是来自模板工具包Intro, Manual page的摘录::


模板工具包是一组Perl模块,实现了一个快速、灵活、强大和可扩展的模板处理系统。它通常用于生成动态Web内容,但同样适用于处理任何类型的文本文档。

在最简单的级别上,它提供了一种轻松的方法来处理模板文件,填充嵌入式变量引用及其等效值。以下是一个模板示例。

亲爱的[% name %],
我们注意到您的账户欠款金额为[% debt %]。
请在[% deadline %]之前结清您的账户,否则我们将被迫撤销您的“许可证”以获得刺激。
管理层。
默认情况下,模板指令嵌入在字符序列[% ... %]中,但您可以更改这些以及其他各种选项来配置Template Toolkit的外观、感觉和工作方式。例如,如果您更喜欢将变量嵌入到Perl样式中,则可以设置INTERPOLATE选项:

亲爱的$name,
我们注意到您的账户欠款$debt。

Perldoc页面


0

请尝试以下方法:

$what = 'server'; # The word to be replaced
$with = 'file';   # Replacement
s/(?<=\${)$what(?=[^}]*})/$with/g;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接