使用awk或cut命令重新排列列

时间:2013-07-29 11:26:32

标签: awk cut

我有1000列的大文件。我想重新排列,以便最后一列应该是第3列。我用过这个,

cut -f1-2,1000,3- file > out.txt

但这不会改变顺序。

有人可以帮忙使用cut或awk吗?

另外,我想重新排列第10列和第11列,如下所示:

示例:

1   10   11   2   3   4   5   6   7   8   9   12  13  14  15  16  17  18  19  20

4 个答案:

答案 0 :(得分:9)

尝试这个awk one-liner:

awk '{$3=$NF OFS $3;$NF=""}7' file

这是将最后一个col移动到第3个col。如果你有1000,那么它用1000th col。

修改

如果文件是制表符分隔的,您可以尝试:

awk -F'\t' -v OFS="\t" '{$3=$NF OFS $3;$NF=""}7' file

<强> EDIT2

添加一个例子:

kent$  seq 20|paste -s -d'\t'                              
1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20

kent$  seq 20|paste -s -d'\t'|awk -F'\t' -v OFS="\t" '{$3=$NF OFS $3;$NF=""}7'
1   2   20  3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  

<强> EDIT3

您没有提供任何输入示例。所以假设您在原始文件中没有空列。 (没有连续的多标签):

kent$  seq 20|paste -s -d'\t'|awk -F'\t'  -v OFS="\t" '{$3=$10 FS $11 FS $3;$10=$11="";gsub(/\t+/,"\t")}7'
1       2       10      11      3       4       5       6       7       8       9       12      13      14      15      16      17      18      19      20

毕竟我们可以在循环中打印这些字段。

答案 1 :(得分:2)

我认为你想要的是:

awk 'BEGIN{FS=OFS="\t"} {$3=$NF OFS $3; sub(OFS "[^" OFS "]*$","")}1' file

根据您的awk版本,这可能对您有用:

awk 'BEGIN{FS=OFS="\t"} {$3=$NF OFS $3; NF--}1' file

如果没有分号后的部分,你的输出中会有尾随标签。

答案 2 :(得分:0)

由于很多人都在寻找这个,即使是最好的awk解决方案也不是很漂亮且易于使用,我想发布用Python编写的解决方案(mycut):

#!/usr/bin/env python3

import sys
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE,SIG_DFL)

#example usage: cat file | mycut 3 2 1

columns = [int(x) for x in sys.argv[1:]]
delimiter = "\t"

for line in sys.stdin:
    parts = line.split(delimiter)

    print("\t".join([parts[col] for col in columns]))

我考虑添加剪切的其他功能,如更改分隔符和使用*来打印重新列的功能。但是它会得到一个自己的页面。

答案 3 :(得分:0)

awk&#39>的shell包装函数使用更简单的语法:

# Usage: rearrange int_n [int_o int_p ... ] < file
rearrange () 
{ 
    unset n;
    n="{ print ";
    while [ "$1" ]; do
        n="$n\$$1\" \" ";
        shift;
    done;
    n="$n }";
    awk "$n" | grep '\w'
}

...实例

echo foo bar baz | rearrange 2 3 1
bar baz foo 

使用bash大括号扩展,rearrange按降序排列第一个和最后5个项目:

echo {1..1000}a | tr '\n' ' ' | rearrange {1000..995} {5..1}
1000a 999a 998a 997a 996a 995a 5a 4a 3a 2a 1a 

/ bin 中排序3个字母的外壳:

ls -lLSr /bin/?sh | rearrange 5 9 
150792 /bin/csh 
154072 /bin/ash 
771552 /bin/zsh 
1554072 /bin/ksh