所以我有一个文本文件,其中包含数字字符串,末尾有一个单词:
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
下一个参数是要执行的脚本。当在标量上下文中使用时, perl
grep()
函数返回匹配的计数(而在列表上下文中,它返回匹配的列表)。即它计算 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