【问题标题】:Bash grep regex issue with two different files两个不同文件的 Bash grep 正则表达式问题
【发布时间】:2018-03-19 15:44:56
【问题描述】:

我有以下命令从仅由大写单词组成的文件中过滤 3 个字母的单词 - 每行一个单词:

grep -E '^[A-Z]{3}$' test

当与包含 10 个单词的文件 test 一起使用时,该命令会返回正确的单词列表。当应用于包含超过 30,000 个单词的更大文件 dico.txt 时,该命令不返回任何内容(仅显示新提示)。

我认为这可能是扩展名或文件大小问题,我已经尝试过:

  • cp test test.txt 匹配大文件*.txt 扩展名
  • 创建一个新文件dico_small.txtdico.txt中选择1000行

...都没有成功。

【问题讨论】:

  • 您确定大文件包含任何 3 个字母的大写单词吗?
  • 确实如此!我还尝试了其他数字(5、6、7 等),但行为相同......
  • 会不会是大文件有 windows 行尾 \r\n 而不是 linux 行尾 \n?在这种情况下,\n 之前的\r 将阻止grep 匹配任何内容,因为您的正则表达式要求在\n 之前直接输入一个字母。 file youLargeFile 的输出是什么?
  • 输出:dico.txt: ASCII text, with CRLF line terminators
  • @wiltomap 跟我想的一样。 CRLF 表示回车\r,换行\n。有关详细信息,请参阅my answer

标签: regex linux bash ubuntu grep


【解决方案1】:

您的大文件有 windows 行尾,即 \r\n 而不是 linux 行尾 \n

\r 称为回车grep 将其视为普通字符。当您编写grep -E "a$" fileWithWindowsLineEndings 时,grep 将找不到任何内容,因为在以\n 结尾的 linux 行前面(在 grep 中表示为 $)总是有一个 \r 而从来没有一个 a

您可以通过删除所有 \r 字符将文件转换为普通的 linux 文件。

tr -d '\r' < fileWithWindowsLineEndings > fileWithLinuxLineEndings
grep -E '...' fileWithLinuxLineEndings

或者,即时转换文件而不保存转换结果:

tr -d '\r' < fileWithWindowsLineEndings | grep -E '...'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 2023-04-09
    • 1970-01-01
    • 2020-12-23
    相关资源
    最近更新 更多