首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析文件的AWK循环

解析文件的AWK循环
EN

Stack Overflow用户
提问于 2022-10-12 14:40:49
回答 2查看 81关注 0票数 -2

我很难理解awk命令,我想稍微修改它(但不能,因为我对代码的理解不够)。这个awk命令的结果是将包含6列的文本文件放在一起。在输出文件中,第一列是输入文件的所有第一列的混合。输出文件的其他列是输入文件的另一列,需要时添加空白,以便仍然与第一列值匹配。

首先,我只想解析这些文件中的一些特定列,而不是所有的6个。我无法在awk循环中找到指定它的位置。

其次,列的头不再是输出文件的第一行。在输出文件中将它作为头也是很好的。

第三,我需要知道数据来自哪个文件。我知道该命令按照文件在执行ls -lh *mosdepth.summary.txt时显示的顺序进行,这样我就可以推断出前6列来自文件1,接下来6列来自文件2,等等。但是,我希望在输出文件中自动获得此信息,以通过推断数据的来源来减少可能的人为错误。

这是awk命令

代码语言:javascript
复制
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

输入文件如下所示

代码语言:javascript
复制
cat file1
chrom   length  bases   mean    min     max
contig_1_pilon  223468  603256  2.70    0       59
contig_2_pilon  197061  1423255 7.22    0       102
contig_6_pilon  162902  1372153 8.42    0       80
contig_19_pilon 286502  1781926 6.22    0       243
contig_29_pilon 263348  1251842 4.75    0       305
contig_32_pilon 291449  1819758 6.24    0       85
contig_34_pilon 51310   197150  3.84    0       29
contig_37_pilon 548146  4424483 8.07    0       399
contig_41_pilon 7529    163710  21.74   0       59
代码语言:javascript
复制
cat file2
chrom   length  bases   mean    min     max
contig_2_pilon  197061  2098426 10.65   0       198
contig_19_pilon 286502  1892283 6.60    0       233
contig_32_pilon 291449  2051790 7.04    0       172
contig_37_pilon 548146  6684861 12.20   0       436
contig_42_pilon 14017   306188  21.84   0       162
contig_79_pilon 17365   883750  50.89   0       1708
contig_106_pilon        513441  6917630 13.47   0       447
contig_124_pilon        187518  374354  2.00    0       371
contig_149_pilon        1004879 13603882        13.54   0       801

错误的输出如下所示

代码语言:javascript
复制
contig_149_pilon        1004879 13603882        13.54   0       801
contig_79_pilon 17365   883750  50.89   0       1708
contig_1_pilon  223468  603256  2.70    0       59
contig_106_pilon        513441  6917630 13.47   0       447
contig_2_pilon  197061  1423255 7.22    0       102     197061  2098426 10.65   0       198
chrom   length  bases   mean    min     max     length  bases   mean    min     max
contig_37_pilon 548146  4424483 8.07    0       399     548146  6684861 12.20   0       436
contig_41_pilon 7529    163710  21.74   0       59
contig_6_pilon  162902  1372153 8.42    0       80
contig_42_pilon 14017   306188  21.84   0       162
contig_29_pilon 263348  1251842 4.75    0       305
contig_19_pilon 286502  1781926 6.22    0       243     286502  1892283 6.60    0       233
contig_124_pilon        187518  374354  2.00    0       371
contig_34_pilon 51310   197150  3.84    0       29
contig_32_pilon 291449  1819758 6.24    0       85      291449  2051790 7.04    0       172

编辑:由于几个用户的输入,我设法回答了我的第1点和第3点,如下所示

代码语言:javascript
复制
awk -F"\t" -v OFS="\t" 'F!=FILENAME { FNUM++; F=FILENAME }

{   B[FNUM]=F;  COL[$1];        C=$1; $1="";       A[C, FNUM]=$4}

END {
        printf("%s\t", "contig")
        for (N=1; N<=FNUM; N++) 
        {   printf("%.5s\t", B[N])}
        printf("\n")
        for(X in COL)
        {
                printf("%s\t", X);
                for(N=1; N<=FNUM; N++) 
                {   printf("%s\t", A[X, N]);
                }
                printf("\n");
        }   
}' file1.txt file2.txt > output.txt

带输出

代码语言:javascript
复制
contig  file1   file2
contig_149_pilon                13.54
contig_79_pilon         50.89
contig_1_pilon  2.70
contig_106_pilon                13.47
contig_2_pilon  7.22    10.65
chrom   mean    mean
contig_37_pilon 8.07    12.20
contig_41_pilon 21.74
contig_6_pilon  8.42
contig_42_pilon         21.84
contig_29_pilon 4.75
contig_19_pilon 6.22    6.60
contig_124_pilon                2.00
contig_34_pilon 3.84
contig_32_pilon 6.24    7.04
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-12 17:43:26

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

在OP中提供的程序中,记录分隔符是默认值,即-character,字段分隔符设置为-character。

Awk程序通常是作为表单pattern { action }的模式-动作对的序列编写的.当action返回非零或非空字符串值时,这些对依次执行状态以执行pattern

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

  1. F!=FILENAME { FNUM++; F=FILENAME }:--这就是说,如果F的值与正在处理的当前FILENAME不同,那么就用1来增加FNUM的值,并用当前的FILENAME更新F的值。

最后,这与检查是否正在处理一个新文件是一样的。这方面的同等版本如下:

(FNR==1) { FNUM++ }

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

  1. { 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”。

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

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

代码语言:javascript
复制
awk 'BEGIN{ FS="\t" }
     { 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 ...
票数 0
EN

Stack Overflow用户

发布于 2022-10-14 22:18:57

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

代码语言:javascript
复制
$ ls *mos*txt
1mosdepth.summary.txt 2mosdepth.summary.txt 3mosdepth.summary.txt

内容如下:

代码语言:javascript
复制
$ 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命令可能是合适的:

代码语言:javascript
复制
$ 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

输出:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
$ 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

输出:

代码语言:javascript
复制
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"将产生:

代码语言:javascript
复制
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"将生产:

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74043776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档