我的数据(标签分隔):
1 0 0 1 0 1 1 0 1
1 1 0 1 0 1 0 1 1
1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0
...
我怎么能用精确的线条,例如5'1, 理想输出:
1 0 0 1 0 1 1 0 1
另外,我怎么能用等于或大于(> =)5'1的行来画线, 理想输出:
1 0 0 1 0 1 1 0 1
1 1 0 1 0 1 0 1 1
1 1 1 1 1 1 1 1 1
我试过了,
grep 1$'\t'1$'\t'1$'\t'1$'\t'1
然而,这只会输出连续的'1',这不是我想要的全部。
我想知道是否会有任何简单的方法来实现这一点,谢谢!
答案 0 :(得分:4)
John Bollinger's helpful answer和anishane's answer表明可以与grep
完成,但是,正如已经指出的那样,这非常繁琐,因为正则表达式不是为计算而设计的。
awk
是为基于字段的解析和计算(通常组合与正则表达式来识别而构建的字段分隔符,或者如下所示,字段本身。)
假设您有 GNU awk
,您可以使用以下内容:
正好5 1
s:
awk -v FPAT='\\<1\\>' 'NF==5' file
5个或更多1
s:
awk -v FPAT='\\<1\\>' 'NF>=5' file
特殊变量FPAT
是 GNU awk
扩展程序,允许您通过描述字段本身的正则表达式来标识字段 ,与使用正则表达式在字段之间定义分隔符的标准方法(通过特殊变量FS
或选项-F
)形成对比:
'\\<1\\>'
根据字边界断言1
和\<
将任何“孤立的”\>
(由非字字符包围)标识为字段; \
必须加倍,以便awk
执行的初始字符串解析不会“吃掉”单个\
。标准变量NF
包含当前行中输入字段的 count ,可以轻松进行数值比较。如果条件计算结果为true,则隐式打印手头的输入行(换句话说:NF==5
隐含地与NF==5 { print }
相同,更详细地说,NF==5 { print $0 }
)。
符合POSIX标准的awk
解决方案稍微复杂一点:
正好5 1
s:
awk '{ l=$0; gsub("[\t0]", "") }; length($0)==5 { print l }' file
5个或更多1
s:
awk '{ l=$0; gsub("[\t0]", "") }; length($0)>=5 { print l }' file
l=$0
将输入行($0
)以原始格式保存在变量l
中。
gsub("[\t0]", "")
取代所有\t
和0
个字符。在带有空字符串的输入行中,即有效地删除它们,并且只留下(直接连接)1
个实例(如果有的话)。
length($0)==5 { print l }
只有在l
s的结果字符串(即现在存储的1
的数量)时才打印原始输入行(1
)在修改输入行($0
)中匹配指定的计数。
答案 1 :(得分:2)
您可以使用grep
。但那将是对正则表达式的滥用。
$ cat countme
1 0 0 1 0 1 1 0 1
1 1 0 1 0 1 0 1 1
1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0
$ grep -P '^[0\t]*(1[0\t]*){5}[0\t]*$' countme # Match exactly 5
1 0 0 1 0 1 1 0 1
$ grep -P '^[0\t]*(1[0\t]*){5,}[0\t]*$' countme # Match >=5
1 0 0 1 0 1 1 0 1
1 1 0 1 0 1 0 1 1
1 1 1 1 1 1 1 1 1
答案 2 :(得分:2)
你可以这样做以获得恰好五个'1'的行:
grep '^[^1]*\(1[^1]*\)\{5,5\}[^1]*$'
您可以将其简化为至少五个'1:
grep '\(1[^1]*\)\{5,\}'
枚举量词(\{n,m\}
)使您可以方便地指定子模式的连续匹配数的特定数量或范围。但是,为了避免匹配具有额外匹配的行到这种模式,您还必须将其锚定到行的开头和结尾。
另一个诀窍是确保第一个1
之前,1
之间和最后一个1
之间的差距匹配。在您的情况下,所有这些差距都可以非常简单地表示为除1
以外的零个或多个字符的范围:[^1]*
。将这些部分放在一起就可以得到上述正则表达式。
答案 3 :(得分:1)
做
sed -nE '/^([^1]*1[^1]*){5}$/p' your_file
正好5场比赛和
sed -nE '/^([^1]*1[^1]*){5,}$/p' your_file
5场或更多场比赛。
注意:在GNU sed中,您可能无法在联机帮助页中看到-E
选项,但它受支持。使用-E
可以移植到Mac OSX。
答案 4 :(得分:1)
perl
$ perl -ane 'print if (grep {$_==1} @F) == 5' ip.txt
1 0 0 1 0 1 1 0 1
$ perl -ane 'print if (grep {$_==1} @F) >= 5' ip.txt
1 0 0 1 0 1 1 0 1
1 1 0 1 0 1 0 1 1
1 1 1 1 1 1 1 1 1
-a
自动拆分空格上的输入行并保存到@F
数组grep {$_==1} @F
返回包含@F
数组中元素的数组,这些元素完全等于1
(grep {$_==1} @F) == 5
,将根据数组-ane
选项