指定匹配重复为0或4(不是1,2,3)

时间:2018-02-23 18:48:42

标签: linux shell grep

我需要在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,,

2 个答案:

答案 0 :(得分:2)

$ 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,,

答案 1 :(得分:1)

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

e.g。使用GNU awk为第3个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,