【问题标题】:grep regular expression to search a number sequencegrep 正则表达式搜索数字序列
【发布时间】:2014-11-30 22:20:59
【问题描述】:

我有一个大文本文件,我想用 grep 搜索。文件结构如下:

8071656799 4661447177 0355654334 3019852932 8351070080 3427747396 : 3099000001
8711668395 3649821348 9956324354 5011010810 9136023566 9366447433 : 3099000002
5082147211 3084342012 9526906615 7367215108 0922482666 6485161555 : 3099000003
4029562459 5180764444 6007631229 0296033611 6410243961 1599676529 : 3099000004
2029562935 7403306551 4667331755 4708680737 0948271458 0585681992 : 3099000005
3980586858 2774838233 2196908474 1817405080 5501649035 3043116116 : 3099000006
4821697167 9339115830 6953440258 6707173876 7188037671 5127476767 : 3099000007
0341392607 4082292483 7807211229 1753819242 4269141779 6567687980 : 3099000008

我想查找特定的数字序列,同时忽略空格、冒号、行尾和每行的最后 10 位数字。例如 8034277473968711 将出现在前两行:

80 3427747396 : 3099000001 8711

拜托,你能帮我解决这个任务的 grep 正则表达式吗?或任何其他解决此问题的方法。谢谢。

【问题讨论】:

  • 前两行可以用其他方式匹配相同的序列。
  • 我不相信它在正则表达式中是实用的——你最喜欢的编程语言是什么? :)
  • 您只是在寻找给定序列的出现次数吗?还是您需要知道它们在文件中的位置?我想知道我们是否不能删除所有不需要的字符(空格和每行的最后 10 位数字),然后以这种方式搜索出现的次数。
  • Linux 还是 Windows?还是windows变成Linux程序?还是在 Windows 下运行 Linux?
  • @Lev Levitsky:怎么样?

标签: regex linux windows grep cygwin


【解决方案1】:

试试这个:

sed -e 's/\s//g' < sed -e 's/:[0-9]\+$//g' < inputFileName | sed -e ':a;N;$!ba;s/\n//g' | grep -o "8034277473968711"

我在 AWS Ubuntu 14.04 microInstance 中对此进行了测试。

我们在这里通过一系列seds 运行和管道它,并使用 grep -o 关闭它。 -o 标志可防止出现大量带有任意突出显示的文本,因为您正在处理大型数据集。它现在应该只显示结果,同时消除所有你不想要的东西。

inputFileName 替换为您的文件名,括号中的数字替换为您想要搜索的任何内容(没有空格,只有直号)。

祝你好运!

【讨论】:

  • 不幸的是,在 cygwin 下,您的解决方案会产生“-bash: sed: No such file or directory”错误。我试图将单引号更改为双引号,但失败了。有人熟悉 cygwin 吗?
  • 嗨米拉。尝试使用双引号中的完整路径 - 即“C:\Users\My User\My File.format”。老实说,我会使用 Linux VirtualBox(或 AWS MicroInstance)来适应 Linux 环境。在 Cygwin 上学习很困难,因为文件系统的解释不同——通常会导致路径复杂化等问题。
  • 那个windows路径,你的意思是/cygdrive/c/Users/My\ User/My\ File.format
  • 我确实做到了。谢谢!
  • 另外 - 我使用 Cygwin 已经有好几年了,所以如果我错了,请纠正我 - 但我认为你可以将路径封装在括号中并避免使用转义序列 \ 表示路径名中的空格,IE 使用"/cygdrive/c/Users/My User/My File.format"
【解决方案2】:

第 1 步:
使用此模式捕获所有可能的数字序列

(?=((?:\d(?:\s:\s\d+\r?\n|\s)?){16}))\d

Demo


第 2 步:
循环遍历以前的匹配项并使用此模式执行替换

\s:\s\d+\r?\n|\s

什么都没有替换


第 3 步:
将第 2 步的结果与您想要的序列进行比较 8034277473968711
在第 49 场比赛中找到的比赛。

【讨论】:

  • 为什么需要第一步?
  • @Aprillion,查找并捕获所有可能的数字序列。
  • 重复自己不会让你的理由更清楚 - 是什么阻止你直接在源数据上应用第 2 步?你称之为步骤1的任意捕获组的七头龙应该有什么好处?你选择 16 是因为 OP 中的示例恰好有 16 位数字吗?
  • 我闻到讽刺的味道,但没关系。我将此语句 I would like to find certain sequence of numbers 解释为连续 16 位数字,可能位于源数据中的任何位置,并被空格 \s 和/或 \s:\s\d+ 打断,我正在生成所有可能的场景(步骤 #1)以查找匹配在完整源数据中的位置作为步骤#2 将改变它。我希望它现在有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 2011-04-08
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多