如何在perl sed-like find / replace命令中跳过不匹配?

时间:2014-09-19 20:01:43

标签: regex perl sed

给出这个简单的sed命令:

echo "abc\nxyz" | sed "s/abc/***/"

等效的Perl版本是

echo "abc\nxyz" | perl -pe "s/abc/***/" 

Sed让我只输出这样的匹配行:

echo "abc\nxyz" | sed -n "s/abc/***/p"

如何使用Perl做到这一点?

仅供参考,我想使用Perl的正则表达式引擎,它似乎比sed更全面,但我想要这个sed选项。

2 个答案:

答案 0 :(得分:3)

Perl的-p选项意味着在输入的每一行上执行-e ...的操作,然后打印。更改为-n表示读取文件的每一行,并在每个行上执行-e ...。因此,实现您想要的简单方法如下:

echo "abc\nxyz" | perl -ne "print if s/abc/***/"

答案 1 :(得分:1)

在Perl中,-p开关设置一个迭代输入的隐式循环,并在循环的每次迭代后打印$_的内容。 Perl还有-n开关,要求此隐式循环中的代码处理自己的输出:

echo "abc\nxyz" | perl -ne 's/abc/***/ && print'

perlrun中描述了-p-n个开关。

简而言之,-p形成一个看起来像这样的隐式循环:

while( <> ) {
    # Your code goes here...
}
continue {
    print;
}

-n形成一个隐含的循环,看起来像这样:

while( <> ) {
    # Your code goes here....
}

因此,对于-n,您必须明确指定何时生成输出,以及该输出应该是什么。通过重新获得对输出的控制,您可以合并允许“打印”的逻辑。仅在满足某些条件时才发生,例如正则表达式匹配。在我的例子中,如果匹配成功,我们将使用逻辑短路来触发打印。