【问题标题】:egrep two identical numbers and two identical letters n timesegrep 两个相同的数字和两个相同的字母 n 次
【发布时间】:2017-12-06 00:11:52
【问题描述】:

您好,我在使用 egrep 命令时遇到了问题。这是我的问题: 假设我在这些词上运行了一个 for 循环:

99aa88bb99aa88bb 9a9a 11bb11bb 11bb11dd 12aa12aa
33aa33bb33aa33bb 

如果单词有两个相同的数字两个相同的字母并且该单词重复,我只想打印它。例如,在这种情况下,应该打印的唯一单词是:

99aa88bb99aa88bb
11bb11bb
33aa33bb33aa33bb

因为每个单词至少有一组或多组两个相同的数字和两个相同的字母,然后它会重复自己

这是另一个例子,我在循环中遍历这些单词:

 aa99aa99 00aa00bb00aa00bb 44aa44aac
 2222aaaa2222aaaa 11cc11cc11cc11cc 

应该打印的唯一单词是

 00aa00bb00aa00bb
 11cc11cc11cc11cc

因为上面提到的。 我真的很难做到这一点我当前不起作用的命令是:

egrep "^((([0-9])\3([a-z])\4)(([0-9])\6([a-z])\7))\1*$" tmp

它不工作的原因是因为它会为我打印如下字样:

11bb11dd

这是不允许的。

任何帮助将不胜感激。

【问题讨论】:

  • 称它们总是长度相等的单词公平吗?或者它们可以变化?
  • @Inian 是的,可以这么说

标签: linux bash unix grep


【解决方案1】:

试试这个:

$ cat ip.txt
99aa88bb99aa88bb 9a9a 11bb11bb 11bb11dd 12aa12aa
33aa33bb33aa33bb 
 aa99aa99 00aa00bb00aa00bb 44aa44aac
 2222aaaa2222aaaa 11cc11cc11cc11cc 

$ grep -owE '(([0-9])\2([a-z])\3([0-9])\4([a-z])\5)\1+|(([0-9])\7([a-z])\8)\6' ip.txt
99aa88bb99aa88bb
11bb11bb
33aa33bb33aa33bb
00aa00bb00aa00bb
11cc11cc11cc11cc

这有两种情况

1) (([0-9])\2([a-z])\3([0-9])\4([a-z])\5)\1+ 有 8 个字符结构至少重复一次 - 这是关键,使用 \1* 将错误匹配 11bb11dd

2) (([0-9])\7([a-z])\8)\6 这有 4 个字符结构,只重复一次


如果您将它们放在不同的行上,则可以这样做

grep -xE '(([0-9])\2([a-z])\3([0-9])\4([a-z])\5)\1+|(([0-9])\7([a-z])\8)\6'


如果还必须匹配11bb11bb11bb,请使用\6+


或者,使用Nahuel Fouilleul这个非常聪明的建议

$ grep -owE '((([0-9])\3([a-z])\4)+)\1+' ip.txt
99aa88bb99aa88bb
11bb11bb
33aa33bb33aa33bb
00aa00bb00aa00bb
11cc11cc11cc11cc
  • (([0-9])\3([a-z])\4)+ 构成基本的 4/8/12/16/etc 字符,由重复的数字和重复的字母组成
  • 然后在外部组中捕获,然后至少重复一次


请注意,如果输入很大,并且您有 PCRE -P 选项,请使用它而不是 -E,因为反向引用会快得多,至少在 GNU grep 的情况下是这样

【讨论】:

  • 为什么不grep -oE '\b((([0-9])\3([a-z])\4)+)\1\b'?或grep -oEw '((([0-9])\3([a-z])\4)+)\1'
  • @NahuelFouilleul 确实非常聪明.. 不会匹配 11bb11bb11bb 虽然.. 我不确定 OP 是否愿意
  • 确实是因为单词边界,但是可以修复在\1 之后添加+
猜你喜欢
  • 1970-01-01
  • 2015-08-12
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
相关资源
最近更新 更多