2014-09-19 60 views
3

鉴于这种简单的sed命令:如何在perl sed-like find/replace命令中跳过不匹配?

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

等效Perl版本是

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

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

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

如何做到这一点与Perl的?我想使用Perl的正则表达式引擎,它比sed更加全面,但是我想要这个sed选项。

+1

尝试['super-sed'](https://directory.fsf.org/wiki/Super-sed)。 'sed'从外面看,'perl'从里面看! – 2014-09-19 20:17:52

回答

1

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

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

-p-n开关在perlrun说明。

总之,-p形成一个隐含的循环,看起来是这样的:

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

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

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

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

+0

完美!谢谢! – clay 2014-09-19 20:20:23

+0

这是'perl -p'的一种很差的表示形式,它可以逐行读取输入文件,并且可以打印它们,无论它们是否被代码修改。 *“打印每个发生的转化的结果”*是错误的。 – Borodin 2014-09-19 20:39:49

+0

@Borodin澄清了前两句话。 – DavidO 2014-09-19 20:50:04

3

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

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

谢谢!这个答案也可以,但我只能接受一个。 – clay 2014-09-19 20:20:40