我有一个包含 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