【问题标题】:AWK loop to parse fileAWK 循环解析文件
【发布时间】:2022-10-15 06:18:57
【问题描述】:

我无法理解我想稍微更改的 awk 命令(但不能,因为我对代码了解不够)。 此 awk 命令的结果是将具有 6 列的文本文件一起解析(总是相同的列顺序,但包含可能不同的数据)。

首先,我只想解析这些文件中的一些特定列,而不是全部 6 个。我不知道在 awk 循环中在哪里指定它。

其次,列的标题不再是输出文件的第一行。最好将它作为输出文件中的标题。

第三,我需要知道数据来自哪个文件。我知道该命令在执行 ls -lh *mosdepth.summary.txt 时按照文件出现的顺序获取文件,因此我可以推断前 6 列来自文件 1,接下来的 6 列来自文件 2,等等。但是,我想在输出文件中自动包含这些信息,以减少通过推断数据来源可能造成的潜在人为错误。

这是awk命令

awk -F"\t" -v OFS="\t" 'F!=FILENAME { FNUM++; F=FILENAME }

{       COL[$1]++;        C=$1; $1="";        A[C, FNUM]=$0 }

END {
        for(X in COL)
        {
                printf("%s", X);
                for(N=1; N<=FNUM; N++) printf("%s", A[X, N]);
                printf("\n");
        }
}' *mosdepth.summary.txt > Se_combined.coverage.txt

输入数据如下所示 enter image description here

【问题讨论】:

  • 请更新问题以包含示例输入数据(以文本形式,我们可以将其剪切粘贴到我们的环境中;不要作为图像发布)、您的代码生成的(错误的)输出以及(正确的)预期输出;提供示例输入时,请提供来自 2-3 个不同文件的 5-10 行,然后(错误的、预期的)输出应与这些示例输入相对应
  • 对于 1,使用 $2, $3, $4 而不是 $0 仅处理这 3 列。对于 3,文件编号在 N,因此您可以在输出中打印它。

标签: loops awk


【解决方案1】:

awk 处理记录中的文件,其中记录由记录分隔符RS 分隔。每条记录都在字段中拆分,其中字段分隔符由-F 标志可以定义的变量FS 定义。

在 OP 中介绍的程序的情况下,记录分隔符是默认值,即 <newline>-字符,字段分隔符设置为 <tab>-字符。

awk 程序通常被编写为pattern { action } 形式的模式-动作对序列。当pattern 返回非零或非空字符串值时,这些对按顺序执行并声明为执行action

在当前程序中有三个这样的动作模式对:

  1. F!=FILENAME { FNUM++; F=FILENAME }:这表示如果F 的值与当前处理的FILENAME 不同,则将FNUM 的值增加1,并将F 的值更新为当前的FILENAME

    最后,这与仅检查我们是否正在处理新文件相同。等效版本是:

    (FNR==1) { FNUM++ }
    

    内容如下:如果我们正在处理当前文件的第一条记录(FNR),那么增加文件计数FNUM.

  2. { COL[$1]++; C=$1; $1=""; A[C, FNUM]=$0 }: 因为没有模式,所以默认为真。因此,在这里,对于每条记录/行增量,您在第一列中看到值的次数并将其存储在关联数组 COL(键值对)中。记住C 中的第一个字段并将当前记录的值存储在数组A 中,但删除第一个字段。因此,如果第二个文件的记录读取“foo A B C D”,并且foo 已经被看到了 3 次,那么,COL["foo"] 将等于 4,A["foo",2] 将读取“A B C D”。

  3. END{ ... }这是一个特殊的模式-动作对。这里的END 表示这个action 应该只在最后执行,当所有文件都处理完之后。 end 语句的作用很简单,它只是打印每个文件的所有记录。包括空记录。

    最后,整个脚本可以简化为以下内容:

    awk 'BEGIN{ FS="	" }
         { file_list[FILENAME]
           key_list[$1]
           record_list[FILENAME,$1]=$0 }
         END { for (key in key_list)
                 for (fname in file_list) 
                    print ( record_list[fname,key] ? record_list[fname,key] : key )
         }' file1 file2 file3 ...
    

【讨论】:

  • 抱歉,不小心点了帖子,还在努力。
【解决方案2】:

假设您的 '*mosdepth.summary.txt' 文件如下所示:

$ ls *mos*txt
1mosdepth.summary.txt 2mosdepth.summary.txt 3mosdepth.summary.txt

内容是:

$ cat 1mosdepth.summary.txt
chrom   length  bases   mean    min max
contig_1_pilon  223468  1181176 5.29    0   860
contig_2_pilon  197061  2556215 12.97   0   217
contig_6_pilon  162902  2132156 13.09   0   80


$ cat 2mosdepth.summary.txt
chrom   length  bases   mean    min max
contig_19_pilon 286502  2067244 7.22    0   345
contig_29_pilon 263348  2222566 8.44    0   765
contig_32_pilon 291449  2671881 9.17  0 128
contig_34_pilon 51310   525393  10.24   0   47

$ cat 3mosdepth.summary.txt
chrom   length  bases   mean    min max
contig_37_pilon 548146  6652322 12.14   0   558
contig_41_pilon 7529    144989  19.26   0   71

以下awk 命令可能是合适的:

$ awk -v target_cols="1 2 3 4 5 6" 'BEGIN{split(target_cols, cols," ")} 
 NR==1{printf "%s ", "file#"; for (i=1;i<=length(cols);i++) {printf "%s ", $cols[i]} print ""} 
FNR==1{fnbr++} 
FNR>=2{printf "%s ", fnbr; for (i=1;i<=length(cols);i++) {printf "%s ", $cols[i]} print ""}' *mos*txt | column -t

输出:

file#  chrom            length  bases    mean   min  max
1      contig_1_pilon   223468  1181176  5.29   0    860
1      contig_2_pilon   197061  2556215  12.97  0    217
1      contig_6_pilon   162902  2132156  13.09  0    80
2      contig_19_pilon  286502  2067244  7.22   0    345
2      contig_29_pilon  263348  2222566  8.44   0    765
2      contig_32_pilon  291449  2671881  9.17   0    128
2      contig_34_pilon  51310   525393   10.24  0    47
3      contig_37_pilon  548146  6652322  12.14  0    558
3      contig_41_pilon  7529    144989   19.26  0    71

或者,以下将输出文件名而不是文件#:

$ awk -v target_cols="1 2 3 4 5 6" 'BEGIN{split(target_cols, cols," ")} 
 NR==1{printf "%s ", "fname"; for (i=1;i<=length(cols);i++) {printf "%s ", $cols[i]} print ""} 
FNR==1{fnbr=FILENAME} 
FNR>=2{printf "%s ", fnbr; fnbr="-"; for (i=1;i<=length(cols);i++) {printf "%s ", $cols[i]} print ""}' *mos*txt | column -t

输出:

fname                  chrom            length  bases    mean   min  max
1mosdepth.summary.txt  contig_1_pilon   223468  1181176  5.29   0    860
-                      contig_2_pilon   197061  2556215  12.97  0    217
-                      contig_6_pilon   162902  2132156  13.09  0    80
2mosdepth.summary.txt  contig_19_pilon  286502  2067244  7.22   0    345
-                      contig_29_pilon  263348  2222566  8.44   0    765
-                      contig_32_pilon  291449  2671881  9.17   0    128
-                      contig_34_pilon  51310   525393   10.24  0    47
3mosdepth.summary.txt  contig_37_pilon  548146  6652322  12.14  0    558
-                      contig_41_pilon  7529    144989   19.26  0    71

使用任一命令,target_cols="1 2 3 4 5 6" 指定要提取的目标列。

target_cols="1 2 3" 例如,将产生:

fname                  chrom            length  bases
1mosdepth.summary.txt  contig_1_pilon   223468  1181176
-                      contig_2_pilon   197061  2556215
-                      contig_6_pilon   162902  2132156
2mosdepth.summary.txt  contig_19_pilon  286502  2067244
-                      contig_29_pilon  263348  2222566
-                      contig_32_pilon  291449  2671881
-                      contig_34_pilon  51310   525393
3mosdepth.summary.txt  contig_37_pilon  548146  6652322
-                      contig_41_pilon  7529    144989

target_cols="4 5 6" 将产生:

fname                  mean   min  max
1mosdepth.summary.txt  5.29   0    860
-                      12.97  0    217
-                      13.09  0    80
2mosdepth.summary.txt  7.22   0    345
-                      8.44   0    765
-                      9.17   0    128
-                      10.24  0    47
3mosdepth.summary.txt  12.14  0    558
-                      19.26  0    71

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-04
    • 2015-08-20
    • 2016-10-30
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    相关资源
    最近更新 更多