【发布时间】:2015-10-12 00:09:21
【问题描述】:
我有这个input.txt 文件:
Dog walks in the park
Man runs in the park
Man walks in the park
Dog runs in the park
Dog stays still
They run in the park
Woman runs in the park
我想搜索 runs? 正则表达式的匹配项并将它们输出到文件中,同时在匹配项的两侧用两个星号突出显示匹配项。所以我想要的输出是这样的:
Man **runs** in the park
Dog **runs** in the park
They **run** in the park
Woman **runs** in the park
我想编写一个函数来包装这个 Perl 单行器(它会做一些其他事情),然后使用正则表达式作为参数调用它。我写了以下脚本:
#!/bin/bash
function reg {
perl -ne 's/($1)/**\1**/&&print' input.txt > regfunctionoutput.txt
}
function rega {
regex="$1"
perl -ne 's/($regex)/**\1**/&&print' input.txt > regafunctionoutput.txt
}
perl -ne 's/(runs?)/**\1**/&&print' input.txt > regularoutput.txt
reg 'runs?'
rega 'runs?'
第一个 Perl 单行的输出就是我想要的。但是,当我尝试将其包装在 reg 函数中并将表达式作为参数传递时,我得到的不是所需的输出:
****Dog walks in the park
****Man runs in the park
****Man walks in the park
****Dog runs in the park
****Dog stays still
****They run in the park
****Woman runs in the park
我认为问题在于 $1 作为函数参数与 Perl 单行中的第一个捕获组之间存在一些冲突。所以我创建了第二个函数rega,它首先将该表达式分配给不同的变量,然后才将其传递给Perl。但是输出和之前的函数一样。
那么,如何将正则表达式传递给函数内部的 Perl 单行器?我做错了什么?
【问题讨论】:
-
在函数中加上双引号会发生什么? (即写
perl -ne "s/($1)/**\1**/&&print") -
您可以使用
sed更有效地执行相同的操作。有关如何引用它,请参阅 simbabque 的答案。 -
@Ploutox 使用双引号解决了这个问题。在我之前的测试中,我假设我需要使用双引号来进行变量扩展,但这会导致一些意想不到的结果。现在一切都很好。我需要做更多的测试才能更早地找出问题所在。
-
@PeterCordes 我不能使用 sed,因为我使用的是 perl 正则表达式,其中一些不能直接使用 sed。由于我还在文本编辑器中对它们进行了一些手动操作,因此将表达式移植到 sed 是可以跳过的附加步骤。不过谢谢你的建议。