Awk 计算包含二进制数的行内的比率值;0“&&引用;1“;
我有一个包含2000多行和45001列的数据文件 第一列实际上是解释数据类型的“字符串” 从第2列开始,到第45001列,数据表示为 “1” 或 “0” 例如,行中的数据模式是 (0 0 0 0Awk 计算包含二进制数的行内的比率值;0“&&引用;1“;,awk,gawk,Awk,Gawk,我有一个包含2000多行和45001列的数据文件 第一列实际上是解释数据类型的“字符串” 从第2列开始,到第45001列,数据表示为 “1” 或 “0” 例如,行中的数据模式是 (0 0 0 01 101 101 10 010 01 1 10 0 0) 数据总数为25。在此数据行中,有5个子组仅由数字“1”组成,例如(1111111111111)。子组之间的“0”假定为“分隔符”。所有“1”的总和等于13 我想计算一下 (所有“1”的总数/仅由“1”组成的子组的总数) 就是 (13/5) 我尝试
1 1
01 1
01 1
0 01
0 01 1 1
0 0 0)
数据总数为25。在此数据行中,有5个子组仅由数字“1”组成,例如(11
111
1111
1
111
)。子组之间的“0”假定为“分隔符”。所有“1”的总和等于13
我想计算一下
(所有“1”的总数/仅由“1”组成的子组的总数)
就是
(13/5)
我尝试使用此代码计算所有“1”的总数
awk-F“0”{print NF}'
这个值为13
但我不知道如何进一步计算我想要的比率。
我不知道如何找到每行中的子组数,因为“1”和“0”的发生次数是随机的
希望得到一些帮助来解决这个问题
提前感谢您的帮助。从描述中我不清楚输入文件的格式。假设输入如下所示:
$ cat file
0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0
要计算“一”的数量和“一”组的数量,并计算它们的比率:
$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; print s1/s2}' file
2.6
对于第二行,两个和都是零,这将导致被零除的错误。我们可以通过添加if
语句来避免这种情况,该语句将打印比率(如果存在),或者0/0
不存在:
if (s2>0)print s1/s2; else print s1"/"s2
完整的代码现在是:
$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; if (s2>0)print s1/s2; else print s1"/"s2}' file
2.6
0/0
$awk'{f=0;s1=0;s2=0;对于(i=2;i0)打印s1/s2;否则打印s1”/“s2}文件
2.6
0/0
工作原理
代码使用三个变量f
是一个标志,如果我们当前在一组“1”中,则为真(1),否则为假(0)s1
是行中的编号s2
是一行中的一组数
在每行的开头,我们初始化变量f=0;s1=0;s2=0
如果我们遇到至少一个,我们将打印比率用于(i=2;i0)打印s1/s2;否则打印s1”/“s2}
。否则,我们将打印s1/s2
0/0
- 这里有一个
awk
可以满足您的需要:
cat file
data 0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0
data 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
data 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
data 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BMR_10@O24-BMR_6@O13-H13 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1
data 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1
张贴准确的输入。ti数字前后是否有空格?这是示例数据[BMR_10@O24-BMR_6@O13-H131101110110110110110110110110110111]。第一列是字符串,其余仅为一行中的数据。我无法显示实际文件,因为文件大小约为5MB。但是,主席先生,有些行的数据包含全部为零的行,例如(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)。所以当我尝试的时候,我会说([vijay@glycogpu处理原始数据]$。/find-sum-and-ratio.sh 947 17 55.7059 awk:(FILENAME=outPut3.dat FNR=2)致命:尝试用零除)。这有可能克服吗?@Vijay好的。更新后的答案有代码来处理。如果在数据信息中添加列号
1
,则不会给出正确的数据。OP:从第2列开始,直到第45001列,数据表示为0或1
如果最后一列包含1
,则不会给出正确的数据。例如,试试看,echo data 011 | awk-F1'{gsub(+/,“”);n=split($0,a,“[^1]+”)-2;print(n?(NF-1)/n:“0”)}
。结果应该是2,代码返回0。@John1024它也将失败,因为列1
info列确实包含1
,与OPs注释一样。将尝试修复它。使用新的示例数据进行更新以计算正确。
$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; if (s2>0)print s1/s2; else print s1"/"s2}' file
2.6
0/0
cat file
data 0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0
data 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
data 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
data 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BMR_10@O24-BMR_6@O13-H13 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1
data 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1
awk '{$1="";$0="0 "$0" 0";t=split($0,b,"1")-1;gsub(/ +/,"");n=split($0,a,"[^1]+")-2;print (n?t/n:0)}' t
2.6
0
25
11
5.5
3