【问题标题】:Specifying Match Repetition for 0 or 4 (not 1, 2, 3)为 0 或 4(不是 1、2、3)指定匹配重复
【发布时间】:2018-02-23 18:48:41
【问题描述】:

我需要在 grep 中指定正则表达式,以便它只匹配重复组的 0 或 4。

例如, 接受以下所有情况:

Hello,
Hello,abcd

但不接受以下所有情况:

Hello,a
Hello,ab
Hello,abc

我尝试了多种模式都没有成功。

echo "Hello,a" | grep -E "Hello,[[:alnum:]]{0,4}"`
Hello,a

echo "Hello,12" | grep -E "Hello,[[:alnum:]]{4}?"
Hello,12

echo "Hello,12" | egrep "Hello,([[:alnum:]]{4})?"
Hello,12

echo "Hello,12ab" | grep "Hello,([[:alnum:]]{4})?"

以下模式有效,但我想找到一种优雅的方式来做到这一点。

$ echo "Hello,123456," | grep -E "Hello,[[:alnum:]]{4},$|Hello,,$"
$ echo "Hello,12345," | grep -E "Hello,[[:alnum:]]{4},$|Hello,,$"
$ echo "Hello,1234," | grep -E "Hello,[[:alnum:]]{4},$|Hello,,$"
Hello,1234,
$ echo "Hello,123," | grep -E "Hello,[[:alnum:]]{4},$|Hello,,$"
$ echo "Hello,12," | grep -E "Hello,[[:alnum:]]{4},$|Hello,,$"
$ echo "Hello,1," | grep -E "Hello,[[:alnum:]]{4},$|Hello,,$"
$ echo "Hello,," | grep -E "Hello,[[:alnum:]]{4},$|Hello,,$"
Hello,,

【问题讨论】:

  • 你试过Hello,([[:alnum:]]{4})?吗?
  • @LohmarASHAR,我做到了。它对我不起作用。
  • 在你的正则表达式末尾添加$grep -E "Hello,[[:alnum:]]{4}?$"
  • 抱歉,我过去和现在都在打电话,还没有测试过。

标签: linux shell grep


【解决方案1】:
$ cat ip.txt
Hello,
Hello,abcd
Hello,a
Hello,ab
Hello,abc

$ grep -xE 'Hello,([[:alnum:]]{4})?' ip.txt 
Hello,
Hello,abcd
  • ([[:alnum:]]{4})? 将不匹配任何内容或 alnum 字符匹配四次
  • -x 选项,以便仅匹配整行。相当于使用grep -E '^Hello,([[:alnum:]]{4})?$'


关于 OP 尝试的一些说明

$ # missing -E option
$ echo "Hello,12ab" | grep 'Hello,([[:alnum:]]{4})?'
$ echo "Hello,12ab" | grep -E 'Hello,([[:alnum:]]{4})?'
Hello,12ab

$ # example when there is trailing ,
$ echo "Hello,1234," | grep -E 'Hello,([[:alnum:]]{4})?,'
Hello,1234,
$ echo "Hello,," | grep -E 'Hello,([[:alnum:]]{4})?,'
Hello,,

【讨论】:

    【解决方案2】:

    如果您只想要零次或其他单次重复次数,请使用@Sundeeps 答案,否则您可以使用 awk 作为查找特定重复次数问题的通用解决方案。

    例如使用 GNU awk 匹配第三个 arg 以检查 Hello, 之后的 12、17 或 53 个字符:

    awk 'match($0,/Hello,([[:alnum:]]*)/,a) && length(a[1]) ~ /^(12|17|53)$/'
    

    请注意,检查 12、17 或 53 以外的某个数字只是对比较的简单否定:

    awk 'match($0,/Hello,([[:alnum:]]*)/,a) && length(a[1]) !~ /^(12|17|53)$/'
    

    当应用于您的原始问题时:

    $ cat file
    Hello,
    Hello,abcd
    Hello,a
    Hello,ab
    Hello,abc
    Hello,123456,
    Hello,12345,
    Hello,1234,
    Hello,123,
    Hello,12,
    Hello,1,
    Hello,,
    

    .

    $ awk 'match($0,/Hello,([[:alnum:]]*)/,a) && length(a[1]) ~ /^(0|4)$/' file
    Hello,
    Hello,abcd
    Hello,1234,
    Hello,,
    
    $ awk 'match($0,/Hello,([[:alnum:]]*)/,a) && length(a[1]) !~ /^(0|4)$/' file
    Hello,a
    Hello,ab
    Hello,abc
    Hello,123456,
    Hello,12345,
    Hello,123,
    Hello,12,
    Hello,1,
    
    $ awk 'match($0,/Hello,([[:alnum:]]*)/,a) && length(a[1]) ~ /^(1|3|5)$/' file
    Hello,a
    Hello,abc
    Hello,12345,
    Hello,123,
    Hello,1,
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-02
      • 1970-01-01
      • 2021-07-04
      • 2015-04-07
      • 2021-11-15
      • 2019-08-21
      • 1970-01-01
      相关资源
      最近更新 更多