如何使用 awk 将下一行带到第一行的末尾,并用逗号分隔?

如何使用 awk 将下一行带到第一行的末尾,并用逗号分隔?

我已经从公开可用的数据库中下载了一些.fa格式的序列。我想生成一个.csv文件,其中包含序列的名称及其长度,以逗号分隔。输入文件是这样的:

>cel-let-7-5p MIMAT0000001 Caenorhabditis elegans let-7-5p
UGAGGUAGUAGGUUGUAUAGUU
>cel-let-7-3p MIMAT0015091 Caenorhabditis elegans let-7-3p
CUAUGCAAUUUUCUACCUUACC
>cel-lin-4-5p MIMAT0000002 Caenorhabditis elegans lin-4-5p
UCCCUGAGACCUCAAGUGUGA
>cel-lin-4-3p MIMAT0015092 Caenorhabditis elegans lin-4-3p
ACACCUGGGCUCUCCGGGUACC
>cel-miR-1-5p MIMAT0020301 Caenorhabditis elegans miR-1-5p
CAUACUUCCUUACAUGCCCAUA

要选择标题行的第一个条目,并在下一行打印读数的大小,我使用以下命令:

grep -A 1 "^>" file_name.fa | awk '{print($1); getline; print length($0)}'

这就是我得到的。输出:

>cel-let-7-5p
22
>cel-let-7-3p
22
>cel-lin-4-5p
21
>cel-lin-4-3p
22
>cel-miR-1-5p
22

但是,在我想要的输出中,我想制作一个.csv可以导出到 Excel/R/python 的文件。预期输出:

cel-let-7-5p,22
cel-let-7-3p,22
cel-lin-4-5p,21
cel-lin-4-3p,22
cel-miR-1-5p,22

我有什么办法可以做到这一点吗?我无法在网上找到相关帮助。

答案1

(避免使用getline()哪里不是绝对需要的):

$ awk '
    /^>/{sub(/^>/, "");printf "%s,", $1;next}    # process lines starting with '>'
    {print length()}                             # other lines
' file_name.fa 

输出

cel-let-7-5p,22
cel-let-7-3p,22
cel-lin-4-5p,21
cel-lin-4-3p,22
cel-miR-1-5p,22

答案2

假设每个标题行之后只有一个序列行,您可以将序列移动到标题的末尾,然后用于awk提取标题的第一部分和末尾的序列长度。

使用paste,读取行并将其粘贴到两个制表符分隔的列中,然后将它们传递给awk进行处理:

$ paste - - <file | awk -v OFS=, '{ sub("^>",""); print $1, length($NF) }'
cel-let-7-5p,22
cel-let-7-3p,22
cel-lin-4-5p,21
cel-lin-4-3p,22
cel-miR-1-5p,22

sub()命令删除起始>字符。

答案3

$ awk -F'[> ]' '{ printf ("%s", NR%2?$2",":length() ORS ) }' infile
cel-let-7-5p,22
cel-let-7-3p,22
cel-lin-4-5p,21
cel-lin-4-3p,22
cel-miR-1-5p,22

该代码定义两组空格>字符作为字段分隔符,然后使用三元运算符(condition ? do-if-true : do-if-false)检查行号是否为奇怪的number(NR%2如果行号为奇数,则返回 1),然后它将选择打印第 2 列 + 之后的逗号$2",";否则如果行号是甚至number(NR%2如果行号为偶数,则返回 0),然后它将选择打印length()当前行的 + 输出记录分隔符(ORS,默认为换行符)。

答案4

awk '/^>/ {a=$1; next} {print a,length}' OFS=, file

相关内容