在awk中将列移到最后

时间:2014-01-20 15:35:05

标签: bash awk cut

我想将指定列(第2列)移动到最后一列位置。 我有多个大的制表符分隔文件,包含可变数量的列和行。但是,第2列都需要最后。另一种说法是我希望订单是1,3-last,2。

由此:

Column1 Column2 Column3 ... Column W ColumnX
1 2 3 ... W X
a b c ... apples oranges

对此:

1 3 ... W X 2
a c ... apples oranges b

我对awk很新。通过阅读其他主题,我复制并尝试了各种各样的事情但没有成功。

#doesn't reorder columns

cut -d $'\t' -f1,3-,2 file.in > file.out


#doesn't work and I don't really understand the for(i...) stuff copied from elsewhere:
cat file.in | awk -F'\t' '{print $1,for(i=3;i<=NF;++i) $i,$2}' > file.out

帮助?

任何指向线程/链接的指针,用简单的教育术语解释for(i ...)部分的内容也将受到赞赏。我得到了要点,而不是语法。

3 个答案:

答案 0 :(得分:7)

使用awk

$ awk 'BEGIN{FS=OFS="\t"} {a=$2; for (i=2;i<NF; i++) $i=$(i+1); $NF=a}1' file
1       3       W       X       2
a       c       apples  oranges b

相同
awk 'BEGIN{FS=OFS="\t"} {a=$2; for (i=2;i<NF; i++) $i=$(i+1); $NF=a; print}' file

解释

  • BEGIN{FS=OFS="\t"}将输入和输出字段分隔符设置为标签。
  • a=$2存储第二个值。
  • for (i=2;i<NF; i++) $i=$(i+1)将每个值移到下一个值。
  • $NF=a将最后一个值设置为我们存储的第二个值。
  • 1是一个隐含awk行为的真实条件:{print $0}

答案 1 :(得分:3)

使用GNU awk for gensub():

$ cat file
Column1 Column2 Column3 ...     ColumnW ColumnX
1       2       3       ...     W       X
a       b       c       ...     apples  oranges

$ awk '{print gensub(/([\t][^\t]+)(.*)/,"\\2\\1","")}' file
Column1 Column3 ...     ColumnW ColumnX Column2
1       3       ...     W       X       2
a       c       ...     apples  oranges b

答案 2 :(得分:0)

使用sed

sed -r 's/\W+(\w*)(.*)/\2\t\1/' file