我有一个带有标签计数的基因组数据文件,我想知道一次代表了多少个:
$ grep "^1" file |wc -l
包括以 1 开头的所有行,因此它包括代表 10 次、11、次、100 次、1245 次等的标签。我该如何操作?
Current format
79 TGCAG.....
1 TGCAG.....
1257 TGCAG.....
1 TGCAG......
我只想要以下几行:
1 TGCAG.....
所以它不能包含以 1257 开头的行。笔记:上面的文件是制表符分隔的。
答案1
身体里的疑问
选择以 a 开头1
且后跟空格的行
grep -c '^1\s' file
grep -c '^1[[:space:]]' file
这也将给出行数(不需要调用 wc)
标题中的问题
A1
不是后跟另一个数字(或什么也不):
grep -cE '^1([^0-9]|$)' file
但上述两种解决方案都有一些有趣的问题,请继续阅读。
在问题正文中,用户声称该文件是“制表符分隔”。
分隔符
标签
1
以 a 开头,后跟制表符(命令中的实际制表符)的行。如果分隔符是空格(或任何其他分隔符,或没有分隔符),则此操作会失败:
grep '^1 ' file
空间
1
以 a 开头,后跟空格(命令中的实际空格)的行。如果分隔符是任何其他分隔符或没有分隔符,则此操作将失败:
grep '^1 ' file
制表符或空格
grep '^1( | )' file
grep '^1[[:blank:]]' file
空白
更灵活的选择是包含多个空格(水平和垂直)字符。字符类集由(空格)、(水平制表符)、(回车符)、(换行符)、(垂直制表符)和(换页符)[:space:]
组成。但 grep 无法匹配换行符(这是一个内部限制,只能通过该选项来避免)。可以将其用作分隔符的描述。也可以使用 GNU 可用的简写形式,而且更短:\t
\r
\n
\v
\f
-z
\s
grep -c '^1[[:space:]]` file
grep -c '^1\s' file
但如果分隔符是冒号:
或任何其他标点字符(或任何字母),则此选项将失败。
边界
或者,我们可以使用从数字到“非数字”边界的转换,实际上是“不在[_[:alnum:]]
( _a-zA-Z0-9
) 中的字符”:
grep -c '^1\b' file # portable but not POSIX.
grep -c '^1\>' file # portable but not POSIX.
grep -wc '^1' file # portable but not POSIX.
grep -c '^1\W' file # portable but not POSIX (not match only a `1`) (not underscore in BSD).
这将接受以 1 开头并后跟一些标点符号的有效行。
答案2
听起来你只想要这个:
$ grep '^1\b' a
1 TGCAG.....
1 TGCAG......
对于其中的计数部分:
$ grep -c '^1\b' file
2
答案3
和awk
:
awk '$1 == "1" { print; x++ } END { print x, "total matches" }' inputfile
答案4
使用grep
:
grep -c '^1\s' file
这将匹配任何以 1 开头且后跟空格的行,并提供这些行的计数(无需wc -l
)
$ cat input
79 TGCAG.....
1 TGCAG.....
1257 TGCAG.....
1 TGCAG......
$ grep -Ec '^1\s' input
2