【问题标题】:Why does grep matches all the lines no matter what the pattern为什么无论模式如何,grep 都匹配所有行
【发布时间】:2015-05-31 21:05:39
【问题描述】:

我在使用 grep 时遇到问题。 我有一个文件http://pastebin.com/HxAcciCa,我想检查某些模式。当我试图搜索它时,只要模式已经存在于给定文件中,grep 就会返回所有行。

为了解释更多,这是我正在运行的代码

grep -F  "ENVIRO" "$file_pos" >> blah    

无论我尝试什么,即使我提供一整行作为模式 bash 总是返回所有行。
这些是我正在尝试的变体:

grep -F  "E20" "$file_pos" >> blah
grep E20 "$file_pos" >> blah 
grep C:\E20-II\ENVIRO\SSNHapACS480.dll "$file_pos" >> blah
grep -F C:\E20-II\ENVIRO\SSNHapACS480.dll "$file_pos" >> blah

还有一些奇怪的原因,当向 grep 添加 -x 选项时,尽管存在确切的模式,但它不会返回任何行。

我已经在网络和 bash 文档中搜索了原因,但找不到任何东西。

我的最终测试如下

grep -F -C 1  "E20" "$store_pos" >> blah #store_pos has the same value as $file_pos

我认为可能是在结果之后打印行,但事实并非如此。 我正在使用 blah 文件来查看输出。 我也在使用 Linux mint rebecca。 最后虽然命名很熟悉这个问题和Why does grep match all lines for the pattern "\'"不相似

最后我想说我是 bash 的新手。 我怀疑错误可能是由于主文件http://pastebin.com/HxAcciCa 而不是代码?

【问题讨论】:

  • 您正在附加到blah。您将其截断为空的部分在哪里?
  • grep -F C:\E20-II\ENVIRO\SSNHapACS480.dll "$file_pos" 之类的东西不起作用,如果您希望将反斜杠传递给 grep,则需要对其进行转义或引用。所以:grep -F 'C:\E20-II\ENVIRO\SSNHapACS480.dll' "$file_pos"。这可以与-x 结合使用。但是这个问题应该有相反的效果:你应该没有匹配,而不是每一行都匹配。
  • 文件中的行尾问题?检查 hexdump 或cat -vET filename
  • 显然如果我使用 wc -l 我得到计数​​ 0,我生成了我正在从安装日志中搜索模式的文件,然后我在文件上使用了 grep 并在问题,即pastebin.com/HxAcciCa,将输出放入文件中。没有换行符是因为文件来自安装日志还是来自 grep?
  • $file_pos 的值是多少?如果这是一个空字符串,那么所有的行都会被匹配。

标签: regex bash grep


【解决方案1】:

从 cmets 看来,该文件似乎有分隔行的回车符,而不是 grep 期望的换行符;因此,grep 将文件视为一大行,要么匹配要么不匹配。

(注意:关于如何在“纯文本”文件中分隔行至少有三种不同的约定——unix 使用换行符(\n),DOS/Windows 使用回车后跟换行符(\r\n ),而 MacOS 的前 OSX 版本只使用回车 (\r)。)

我不清楚您的文件是如何以这种格式结束的,但您可以通过以下方式轻松修复它:

tr '\r' '\n' <badfile >goodfile

或即时使用:

tr '\r' '\n' <badfile | grep ...

【讨论】:

  • 谢谢你解决了它。一个问题,为什么 cat 将 '\r' 读为 ^M 而不是 '\r'?
  • @user1544624:表示非打印字符有许多不同的约定。 \r(表示“返回”)是 C 语言约定,使用相当广泛。您可能遇到的其他包括^M(因为回车是 ASCII 代码中的 Control-M)、&lt;CR&gt;(用于回车)、\015(八进制的 ASCII 字符代码),可能还有其他我不考虑副手。
【解决方案2】:
  1. 检查输入文件中的行尾:filewc -l
  2. 检查您确实使用了正确的grepwhich grep
  3. 使用&gt; 重定向输出,或使用| more| less 以免被您附加到的先前尝试混淆。

编辑:您的文件似乎有错误的行尾(可能是旧的 Mac OS (CR))。如果您有 dos2unix,您可以尝试将它们转换为 Unix 样式的行尾 (LF)。

【讨论】:

  • 请看我的 cmets 关于 wc -l,我也在使用正确的 grep,即 /bin/grep
  • 如果你有 dos2unix >= 7.1 你可以检查换行符。 $ dos2unix -i HxAcciCa.htm 369 125 0 no_bom text HxAcciCa.htm 如我所见,该文件有 369 个 DOS 换行符、125 个 Unix 换行符和 0 个 Mac 换行符。如果您不小心将文件转换为 Mac 换行符,请使用 mac2unix 命令将其转换回 Unix 格式
【解决方案3】:

我目前无法使用 PC,但有什么可以帮助您解决问题的方法: 1. 使用 grep --color -F 查看是否匹配正确。 2. 在你的陈述之后,使用 | cat -A 查看是否有任何令人惊讶的控制字符,行应以 $ 结尾,任何其他字符如 \I 或 \M 有时会让人头疼。

我怀疑数字 2,因为它似乎是 Windows 输出。在这种情况下,您可以 cat filename | dos2unix | grep stmt 应该解决它

您是否将 dos2unix 输出另存为另一个文件? 只需仔细检查文件,它应该类似于:

[root@pro-mon9001 ~]# cat -A Test.txt
Windows^M$
Style^M$
Files^M$
Are^M$
Hard ^M$
To ^M$
Parse^M$


[root@pro-mon9001 ~]# dos2unix Test.txt 
dos2unix: converting file Test.txt to Unix format ...

[root@pro-mon9001 ~]# cat -A Test.txt
Windows$
Style$
Files$
Are$
Hard$
To$
Parse$

现在它应该可以正确解析 - 所以只需验证它是否正确转换了文件 祝你好运!

【讨论】:

  • 因为每一行都以 ^M 结尾,这是否意味着格式是 mac??我试过 dos2unix 但它没有改变任何东西。
  • ^M 表示回车,通常用于 Windows 文件。所以也许先运行 dos2unix filename 将其转换为 *nix 样式,然后重试您的语句。您的系统上也可能没有安装 dos2unix,这使得两步过程成为一个很好的测试
  • 我确实使用了 dos2unix,但这并没有帮助。换行数仍为 0。
  • 更新了答案 - 只是您的 ^M 控制字符已从文件中删除
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-12
  • 1970-01-01
  • 2019-04-30
  • 2013-05-27
  • 1970-01-01
  • 2017-02-23
相关资源
最近更新 更多