使用awk或其他方法重新排列文本文件中的8列,其中包含数百个列

时间:2013-10-01 04:28:36

标签: bash awk cut

希望这很简单。

我有一个包含数百列的文本文件。只需要复制其中的8个(不是连续),将它们移动到第5,第6,第7列......然后像以前那样将文件的其余部分移动到第5,6,7列......

我真的不想写出一个包含356个列占位符的awk或cut命令。

谢谢!

更新 - 示例:

A   B   C   D  E  F  G  ...  X  Y  Z

我想要的是:

A   Y   K   L   Z   J   B   C   D   E   F   G   ...   X   Y   Z

感谢您的帮助。

哦,这些字母实际上代表由标签分隔的整个列。

3 个答案:

答案 0 :(得分:0)

有人这样吗?

awk '{$5=$70;$6=$35;$7=$122;$8=$190;$9=$55;$10=$200;$11=$12;$12=$67}1' file

编辑: 这会将某些列移动到位置6到8,然后删除原始位置。

cat file
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    awk '{a[++i]=$0} END {for (i=1;i<=5;i++) printf "%s ",a[i];printf "%s %s %s ",a[16],a[8],a[22];a[16]=a[8]=a[22]="";for (i=6;i<=27;i++) printf "%s ",a[i]}' RS="[ \t]" file | awk '{$1=$1}1' OFS="\t"

    A       B       C       D       E       P       H       V       F       G       I       J       K       L       M       N       O       Q       R       S       T       U       W       X       Y       Z

EDIT2:一个更干净的版本

awk '
    {
    a[++i]=$0
    } 
END {
    for (i=1;i<=5;i++)
        printf "%s\t",a[i]
    printf "%s\t%s\t%s\t",a[16],a[8],a[22]
    a[16]=a[8]=a[22]=""
    for (i=6;i<=27;i++)
        if (a[i])
            printf "%s\t",a[i]
    }
    ' RS="[[:space:]]" file

EDIT3:如果awk不支持此类RS,请使用此解决方案

awk '
    {
    for (i=1;i<=NF;i++)
        a[i]=$i
    } 
END {
    for (i=1;i<=5;i++)
        printf "%s\t",a[i]
    printf "%s\t%s\t%s\t",a[16],a[8],a[22]
    a[16]=a[8]=a[22]=""
    for (i=6;i<=27;i++)
        if (a[i])
            printf "%s\t",a[i]
    }
    ' file

答案 1 :(得分:0)

根据您的comment,这可能适合您:

awk '{FS=OFS="\t"} $7=$7 FS $116 FS $119 FS $121 FS $124 FS $127 FS $129 FS $131 FS $134 FS $137 FS $140 FS $143 FS $146 FS $149 FS $152 FS $155 FS $158' inputfile

编辑:如果你有一个标题,你可以说:

awk 'NR>1 {FS=OFS="\t"} $7=$7 FS $116 FS $119 FS $121 FS $124 FS $127 FS $129 FS $131 FS $134 FS $137 FS $140 FS $143 FS $146 FS $149 FS $152 FS $155 FS $158' inputfile

答案 2 :(得分:0)

这个移动字段而不是复制,但不能有空字段。 无需迭代1-NF,您可以将字段附加到$ 1并通过将它们设置为“”来删除它们,但是您在“孔”中有双重标签。幸运的是,假设您没有任何空字段,可以使用tr删除这些内容。

awk 'BEGIN{FS=OFS="\t"}
{
  $7=$7"\t"$116"\t"$119"\t"$121"\t"$124"\t"$127"\t"$129"\t"$131"\t"$134"\t"$137"\t"$140"\t"$143"\t"$146"\t"$149"\t"$152"\t"$155"\t"$158
  $116=$119=$121=$124=$127=$129=$131=$134=$137=$140=$143=$146=$149=$152=$155=$158=""
  print
}' infile | tr -s "\t" >outfile