管道 awk 和 grep 以保存文件的特定字段

Pipe awk and grep to save a particular field of a file

我想达到的目标:

当前代码

grep "length:" test_reads.fa.contigs.vcake_output | awk -F:'{print }' |sort -g -r > contig.txt

test_reads.fa.contigs.vcake_output的示例内容:

>Contig_11 length:42
ACTCTGAGTGATCTTGGCGTAATAGGCCTGCTTAATGATCGT
>Contig_0 length:99995
ATTTATGCCGTTGGCCACGAATTCAGAATCATATTA

预期输出

>Contig_0 99995
>Contig_11 42

使用您展示的示例,请在此处尝试遵循 awk + sort 解决方案。

awk -F'[: ]' '/^>/{print ,}' Input_file | sort -nrk2

解释:简单的解释就是,运行awk程序读取Input_file首先,将字段分隔符设置为 : 或 space 并检查行是否从 > 开始的条件,然后打印其第一个和第二个字段,然后将其输出(作为标准输入)发送到 sort 命令从第二个字段对其进行排序以获得所需的输出。

也许是这样,结合 grep 和 awk:

awk -F '[ :]' ' == "length" {print , }' file | sort ...

假设:

  • 如果多行的长度相同,则使用 'version' 排序对第一列进行额外排序

向示例输入添加一些额外的行:

$ cat test_reads.fa.contigs.vcake_output
>Contig_0 length:99995
ATTTATGCCGTTGGCCACGAATTCAGAATCATATTA
>Contig_11 length:42
ACTCTGAGTGATCTTGGCGTAATAGGCCTGCTTAATGATCGT
>Contig_17 length:93
ACTCTGAGTGATCTTGGCGTAATAGGCCTGCTTAATGATCGT
>Contig_837 ignore-this-length:1000000
ACTCTGAGTGATCTTGGCGTAATAGGCCTGCTTAATGATCGT
>Contig_8 length:42
ACTCTGAGTGATCTTGGCGTAATAGGCCTGCTTAATGATCGT

一个sed/sort想法:

$ sed -rn 's/(>[^ ]+) length:(.*)$/ /p' test_reads.fa.contigs.vcake_output | sort -k2,2nr -k1,1V

其中:

  • -En - 启用扩展的正则表达式支持并抑制输入数据的正常打印
  • (>[^ ])+) -(第一​​个捕获组)- > 后跟 1 个或多个 non-space 个字符
  • length: - space 后跟 length:
  • (.*) -(第二个捕获组)- 0 个或多个字符(冒号后)
  • $ - 行尾
  • /p - 打印第一个捕获组 + <space> + 第二个捕获组
  • -k2,2nr - 按 reverse numeric order
  • 中的第二个 (spaced-delimited) 字段排序
  • -k1,1V - 按 V 版本顺序
  • 中的第一个 (space-delimited) 字段排序

这会生成:

>Contig_0 99995
>Contig_17 93
>Contig_8 42
>Contig_11 42

这是一个 gnu-awk 解决方案,无需调用 sort:

,只需一条命令即可完成所有操作
awk -F '[:[:blank:]]' '
 == "length" {arr[] = }
END {
   PROCINFO["sorted_in"] = "@ind_num_asc"
   for (i in arr)
      print i, arr[i]
}' file

>Contig_0 99995
>Contig_11 42