链式(管道)greps忽略元字符?

时间:2011-11-10 16:04:38

标签: grep wildcard

我在复杂(链式)grep命令中搜索.行时遇到问题 这是我的错误还是错误?

grep '\.' filename | grep 1    # works correctly (finds lines with '.' and '1')
grep 1 filename | grep '\.'    # fails: ignores 2nd grep, returns lines with or without '.'

导致这种情况的不是管道;这真的是关于grep的事 这坦率地说似乎难以置信,但确实如此:

cat filename | grep 1 | grep '\.'   # works correctly (and provides an easy work-around for the bug)

添加更多保护无济于事:

grep 1 filename | grep '\\.'      # fails

如果通配符后面或前面有东西,它可以工作:

grep 1 filename | grep 'a\.'     #  works
grep 1 filename | grep '\.a'     #  works

但如果某事物是一个范围,那就不行了:

grep 1 filename | grep '[0-9]\.'    # fails
grep 1 filename | grep '\.[0-9]'    # fails

我无法相信这确实是一个错误 - 我必须遗漏一些东西,对吗?

谢谢!

uname -a
Linux conception 2.6.32-33-generic #70-Ubuntu SMP Thu Jul 7 21:09:46 UTC 2011 i686 GNU/Linux

2 个答案:

答案 0 :(得分:1)

首先,“链式”grep命令就像“mauvais ton”。大多数情况下,grep | grep可以替换为具有复杂正则表达式的grep

在其中加注.1

$> cat ./text | grep -P "(\..*1|1.*\.)"
line with 1 and . in it

-P表示perl正则表达式 "(\..*1|1.*\.)"是(.,有些符号和1)或(1,有些符号和.

因此,如果您不太确定使用通配符,正则表达式可能是您有用,安全且功能强大的工具。

$> cat ./text 
line without anything
another line
line with.ok
and one another
line with 1
some text

line with 1 and . in it
empty line
last line

首例grep '\.' filename | grep 1grep 1 filename | grep '\.'cat filename | grep 1 | grep '\.'回归正确答案

line with 1 and . in it

第二个示例grep 1 filename | grep '\\.'失败,因为您正在使用后面的任何符号点击\

答案 1 :(得分:0)

我的愚蠢错误。

我正在写一堆文件,文件名本身包含一个'。':

cat one.file
    1
    2
    3

cat second.file  
    10  
    11  
    12.  

现在

grep 1 *file | grep '\.'

  one.file: 1  
  second.file: 10  
  second.file: 11  
  second.file: 12.  

我看了一下输出,认为第二个grep被忽略了。现在很明显发生了什么,但今天早上真的把我扔了。