使用 grep 查找包含特定字母 X 次的字符串的所有行

使用 grep 查找包含特定字母 X 次的字符串的所有行

所以我有一个文本文件,其中包含数字字符串,末尾有一个单词:

123456 126 2 12456 1256 4 46 12346 123456 4 56 word
24 245 1234 356 12346 6 3 346 245 5 12346 12356 word

我想找到至少有 8 个字符串(其中包含 1 或 6 或两者)的所有行。所以第一行会通过,因为它有 8 个字符串(用空格分隔),其中包含 1 或 6 或两者。第二个只有 7 个字符串,其中包含 1 或 6 或两者。

我尝试了以下正则表达式,但它给出了回溯限制错误:([0-9]*(1|6)[0-9]* .*){8,}

答案1

1下面的代码不是尝试构建正则表达式,而是迭代除最后一个字段之外的所有空白分隔字段,如果计数器包含或 ,则递增计数器6。如果计数器的值为 8 或更大,则输出当前记录:

awk '{ count = 0; for (i = 1; i < NF; ++i) count += ($i ~ "[16]") }; count >= 8' file

以下代码执行相同的操作,但当我们知道要输出记录时停止计数:

awk '{ count = 0; for (i = 1; i < NF && count < 8; ++i) count += ($i ~ "[16]") }; count == 8' file

作为较短的(不可读的)一行(计数器正在运行向下从 8):

awk '{c=8;for(i=1;i<NF&&c;++i)c-=$i~"[16]"}!c' file

答案2

使用 Perl:

$ perl -ane 'print if (grep /[16]/, @F) >= 8' file.txt 
123456 126 2 12456 1256 4 46 12346 123456 4 56 word
  • -a自动将每个输入行拆分为 array @F

  • -n使 perl 运行类似于sed -n(即循环每个输入行,但除非明确告知否则不打印任何内容)。

  • -e下一个参数是要执行的脚本。

  • 当在标量上下文中使用时, perlgrep()函数返回匹配的计数(而在列表上下文中,它返回匹配的列表)。即它计算 array 中匹配元素的数量@F

    请注意,此功能类似于,但是不一样命令grep行程序。perldoc -f grep详情请参阅。


顺便说一句,如果你也想打印匹配的数量,你可以这样做:

$ perl -ane '$x = grep /[16]/, @F; if ($x >= 8) {printf "%2i: %s", $x, $_}' /tmp/junk.txt 
 8: 123456 126 2 12456 1256 4 46 12346 123456 4 56 word

答案3

使用sed

$ sed -En 's/ ?[0-9]*[16][0-9]* /&/p8' input_file
123456 126 2 12456 1256 4 46 12346 123456 4 56 word

相关内容