Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash awk计数发生次数_Bash_Shell_Awk - Fatal编程技术网

Bash awk计数发生次数

Bash awk计数发生次数,bash,shell,awk,Bash,Shell,Awk,我在一个shell脚本中使用这个awk命令来计算$4和$5的总出现次数 awk -F" " '{if($4=="A" && $5=="G") {print NR"\t"$0}}' file.txt > ag.txt && cat ag.txt | wc -l awk -F" " '{if($4=="C" && $5=="T") {print NR"\t"$0}}' file.txt > ct.txt && cat ct.

我在一个shell脚本中使用这个awk命令来计算$4和$5的总出现次数

awk -F" " '{if($4=="A" && $5=="G") {print NR"\t"$0}}' file.txt > ag.txt && cat ag.txt | wc -l
awk -F" " '{if($4=="C" && $5=="T") {print NR"\t"$0}}' file.txt > ct.txt && cat ct.txt | wc -l

awk -F" " '{if($4=="T" && $5=="C") {print NR"\t"$0}}' file.txt > tc.txt && cat ta.txt | wc -l
awk -F" " '{if($4=="T" && $5=="A") {print NR"\t"$0}}' file.txt > ta.txt && cat ta.txt | wc -l
输出是shell中的######(数字)。但是我想去掉ag.txt和cat ag.txt | wc-l,而是像ag=####一样在shell中获得输出

这是输入格式:

>seq1 284 284 A G 27 100 16 11 16 11
>seq1 266 266 C T 27 100 16 11 16 11
>seq1 185 185 T - 24 100 10 14 10 14
>seq1 194 194 T C 24 100 12 12 12 12
>seq1 185 185 T AAA 24 100 10 14 10 14
>seq1 194 194 A G 24 100 12 12 12 12
>seq1 185 185 T A 24 100 10 14 10 14
我希望在shell或文件中以这样的方式输出单个事件,而不是其他模式

AG 2
CT 1
TC 1
TA 1

是的,您尝试执行的所有操作都可能在awk脚本中完成。以下是我如何根据条件计算行数:

awk -F" " '$4=="A" && $5=="G" {n++} END {printf("AG = %d\n", n)}' file.txt
  • Awk脚本由
    condition{statement}
    对组成,所以您可以完全取消
    if
    ——它是隐式的
  • n++
    只要条件匹配,计数器就会递增
  • 在处理最后一行输入后,神奇条件
    END
    为真
这就是你想要的吗?如果只需要行数,为什么要在输出中添加
NR

哦,您可能需要确认是否确实需要
-F”“
。默认情况下,awk在空白处拆分。我认为,只有当您的字段包含嵌入式选项卡时,才需要此选项


根据编辑的问题更新#1

如果你真正想要的是一个配对计数器,那么awk阵列可能是最好的选择。大概是这样的:

awk '{a[$4 $5]++} END {for (pair in a) printf("%s %d\n", pair, a[pair])}' file.txt
这是故障

  • 第一条语句在每一行上运行,并递增一个计数器,该计数器是数组(
    a[]
    )上的索引,该数组的键是从
    $4
    $5
    生成的
  • END
    块中,我们在
    for
    循环中遍历数组,并为每个索引打印索引名称和值
由于awk不保证数组顺序,因此输出将不会以任何特定顺序进行。如果你同意的话,这就足够了。它也应该非常有效,因为它的最大内存使用量是基于可用组合的总数,这是一个有限的集合

例如:

$ cat file
>seq1 284 284 A G 27 100 16 11 16 11
>seq1 266 266 C T 27 100 16 11 16 11
>seq1 227 227 T C 25 100 13 12 13 12
>seq1 194 194 A G 24 100 12 12 12 12
>seq1 185 185 T A 24 100 10 14 10 14
$ awk '/^>seq/ {a[$4 $5]++} END {for (p in a) printf("%s %d\n", p, a[p])}' file
CT 1
TA 1
TC 1
AG 2

根据修改后的输入数据和以前未记录的要求更新#2

有了这些额外的数据,您仍然可以通过单次运行awk来实现这一点,但当然,随着每个新需求的增加,awk脚本变得越来越复杂。让我们将此作为一个较长的单行线来尝试:

$ awk 'BEGIN{v["G"]; v["A"]; v["C"]; v["T"]} $4 in v && $5 in v {a[$4 $5]++} END {for (p in a) printf("%s %d\n", p, a[p])}' i
CT 1
TA 1
TC 1
AG 2
首先(在magic
BEGIN
块中)定义一个数组
v[]
,以记录“有效”记录。计数器上的条件只是验证
$4
$5
都包含数组的成员。其他一切都是一样的

此时,由于脚本运行在多行上,我可能会将其拆分为一个小文件。它甚至可以是一个独立的脚本

#!/usr/bin/awk -f

BEGIN {
  v["G"]; v["A"]; v["C"]; v["T"]
}

$4 in v && $5 in v {
  a[$4 $5]++
}

END {
  for (p in a)
    printf("%s %d\n", p, a[p])
}
这样读起来容易多了

如果你的目标是只计算你在问题中提到的组合,你可以稍微不同地处理数组

#!/usr/bin/awk -f

BEGIN {
  a["AG"]; a["TA"]; a["CT"]; a["TC"]
}

($4 $5) in a {
  a[$4 $5]++
}

END {
  for (p in a)
    printf("%s %d\n", p, a[p])
}
这只验证已经具有数组索引的内容,每个
BEGIN
都为空


增量条件中的括号不是必需的,只是为了清楚起见才包括在内。

是的,您尝试执行的所有操作都可能在awk脚本中完成。以下是我如何根据条件计算行数:

awk -F" " '$4=="A" && $5=="G" {n++} END {printf("AG = %d\n", n)}' file.txt
  • Awk脚本由
    condition{statement}
    对组成,所以您可以完全取消
    if
    ——它是隐式的
  • n++
    只要条件匹配,计数器就会递增
  • 在处理最后一行输入后,神奇条件
    END
    为真
这就是你想要的吗?如果只需要行数,为什么要在输出中添加
NR

哦,您可能需要确认是否确实需要
-F”“
。默认情况下,awk在空白处拆分。我认为,只有当您的字段包含嵌入式选项卡时,才需要此选项


根据编辑的问题更新#1

如果你真正想要的是一个配对计数器,那么awk阵列可能是最好的选择。大概是这样的:

awk '{a[$4 $5]++} END {for (pair in a) printf("%s %d\n", pair, a[pair])}' file.txt
这是故障

  • 第一条语句在每一行上运行,并递增一个计数器,该计数器是数组(
    a[]
    )上的索引,该数组的键是从
    $4
    $5
    生成的
  • END
    块中,我们在
    for
    循环中遍历数组,并为每个索引打印索引名称和值
由于awk不保证数组顺序,因此输出将不会以任何特定顺序进行。如果你同意的话,这就足够了。它也应该非常有效,因为它的最大内存使用量是基于可用组合的总数,这是一个有限的集合

例如:

$ cat file
>seq1 284 284 A G 27 100 16 11 16 11
>seq1 266 266 C T 27 100 16 11 16 11
>seq1 227 227 T C 25 100 13 12 13 12
>seq1 194 194 A G 24 100 12 12 12 12
>seq1 185 185 T A 24 100 10 14 10 14
$ awk '/^>seq/ {a[$4 $5]++} END {for (p in a) printf("%s %d\n", p, a[p])}' file
CT 1
TA 1
TC 1
AG 2

根据修改后的输入数据和以前未记录的要求更新#2

有了这些额外的数据,您仍然可以通过单次运行awk来实现这一点,但当然,随着每个新需求的增加,awk脚本变得越来越复杂。让我们将此作为一个较长的单行线来尝试:

$ awk 'BEGIN{v["G"]; v["A"]; v["C"]; v["T"]} $4 in v && $5 in v {a[$4 $5]++} END {for (p in a) printf("%s %d\n", p, a[p])}' i
CT 1
TA 1
TC 1
AG 2
首先(在magic
BEGIN
块中)定义一个数组
v[]
,以记录“有效”记录。计数器上的条件只是验证
$4
$5
都包含数组的成员。其他一切都是一样的

此时,由于脚本运行在多行上,我可能会将其拆分为一个小文件。它甚至可以是一个独立的脚本

#!/usr/bin/awk -f

BEGIN {
  v["G"]; v["A"]; v["C"]; v["T"]
}

$4 in v && $5 in v {
  a[$4 $5]++
}

END {
  for (p in a)
    printf("%s %d\n", p, a[p])
}
这样读起来容易多了

如果你的目标是只计算你在问题中提到的组合,你可以稍微不同地处理数组

#!/usr/bin/awk -f

BEGIN {
  a["AG"]; a["TA"]; a["CT"]; a["TC"]
}

($4 $5) in a {
  a[$4 $5]++
}

END {
  for (p in a)
    printf("%s %d\n", p, a[p])
}
这只验证已经具有数组索引的内容,每个
BEGIN
都为空

增量条件中的括号不是必需的,包含在