使用 AWK 进行列操作

使用 AWK 进行列操作

我有一个包含 200 多列的文件。出于示例目的,我在这里使用列数较少的文件 (9)。下面是输入文件(几行)

chr10   181243  225933  1   1   1   10  0   36
chr10   181500  225933  1   1   1   106 0   35
chr10   226069  255828  1   1   1   57  0   37
chr10   243946  255828  1   1   1   4   0   27
chr10   255989  267134  1   1   1   87  0   32
chr10   255989  282777  1   1   1   61  0   34
chr10   267297  282777  1   1   1   61  0   37
chr10   282856  283524  1   1   1   92  0   35
chr10   282856  285377  1   1   1   1   0   15
chr10   283618  285377  1   1   1   72  0   33

我想重新排列文件,使我的最后一列(此处为第 9 列)成为输出文件中的第 4 列,然后打印其他所有内容。所以我正在寻找的输出是

chr10   181243  225933  36  1   1   1   10  0
chr10   181500  225933  35  1   1   1   106 0
chr10   226069  255828  37  1   1   1   57  0
chr10   243946  255828  27  1   1   1   4   0
chr10   255989  267134  32  1   1   1   87  0
chr10   255989  282777  34  1   1   1   61  0
chr10   267297  282777  37  1   1   1   61  0
chr10   282856  283524  35  1   1   1   92  0
chr10   282856  285377  15  1   1   1   1   0
chr10   283618  285377  33  1   1   1   72  0

在列数较少的文件上,我可以使用类似的方法来实现上述输出:

awk -v OFS="\t" '{print $1,$2,$3,$9,$4,$5,$6,$7,$8}'

如果现在我有一个包含大量列的文件,如何将文件的最后一列作为第四列,其余部分按原样打印?

答案1

Perl 对此非常简洁:将每一行拆分为单词,弹出最后一个单词并将其插入到索引 3(从 0 开始)

$ perl -lane 'splice @F, 3, 0, pop(@F); print "@F"' file | column -t
chr10  181243  225933  36  1  1  1  10   0
chr10  181500  225933  35  1  1  1  106  0
...

答案2

要将第四个字段替换为最后一个字段:

awk -v OFS="\t" '{ $4 = $NF; $NF=""; print }

插入最后一个字段第四个字段,我们必须有点创意:

awk -v OFS="\t" '{temp=$NF; for( i=NF;i>4;i-- ) {$i=$(i-1)}; $4=temp  ; print}'

这将保留最后一个字段,遍历所有字段并将每个字段向后移动到第四个向前的字段,然后将所需的第四个字段放置到位:

$ echo {1..10} | awk -v OFS="\t" '{temp=$NF; for( i=NF;i>4;i-- ) {$i=$(i-1)}; $4=temp  ; print}'
1   2   3   10  4   5   6   7   8   9

相关内容