2012-03-28

求教:一次 grep 被 perl 调用出现的问题

问题起于我在一个perl脚本下写下了下面一句:

 @diffs = `svn diff -x -w $file | grep '^\+\\s' | sed -e 's/^\+//g`;

是想捕获运行svn diff的结果中,右边文件的差异行。其中 grep ‘^\+\\s' 在shell中的书写是 grep ‘^\+\s’,因为在perl脚本中单个‘\’会被当作转义符,所以用\\s。

在命令行中这条命令这么写:

svn diff -x -w test.c | grep '^\+\s' | sed -e 's/^\+//g

这句在我的cygwin下运行没有问题,在ubuntu上有问题,可能因为cygwin上的grep版本较新,会默认支持“\s”这种简写的正则表达式。实际上准确的写法应该是:

grep -P '^\+\s'

-P 选项使得grep命令支持Perl风格正则表达式。这样在两个环境下,shell命令都是没有问题的,但是Perl脚本中这样写:

@diffs = `svn diff -x -w $file | grep -P '^\+\\s' | sed -e 's/^\+//g`;

却出现了问题,shell报告:

grep: nothing to repeat

svn: Can't write to stream: Broken pipe

 问题看来是因为-P选项,谁知道这是什么原因?这条语句中如果用grep的其他选项,如-e就不会出现这样的错误报告,还望高手指点。