如何在unix中将第一列移到最后一列?

时间:2017-10-03 14:22:07

标签: linux bash unix awk

这是文本文件中的数据。

0.354167 male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50
0.625 male typ_angina 0.792453 0.328767 f left_vent_hyper 0.564885 no 0.677419 down 0 reversable_defect <50
0.645833 male non_anginal 0.433962 0.134703 f left_vent_hyper 0.641221 no 0.483871 flat 0 normal >50_1
0.666667 female asympt 0.481132 0.413242 f left_vent_hyper 0.572519 yes 0.16129 flat 0 reversable_defect >50_1
0.270833 male typ_angina 0.509434 0.269406 f left_vent_hyper 0.816794 no 0.129032 up 0.666667 normal <50

我必须将第一列包含数字数据移动到每一行的最后一列。

例如:

0.354167 male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50

male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50 0.354167

如何使用bash命令?

5 个答案:

答案 0 :(得分:6)

awk 解决方案(不包括所有字段的循环):

awk '{ $(NF+1)=$1; sub(/^[^ ]+ */,"") }1' file.txt
  • $(NF+1)=$1 - 将第一个字段追加到最后(作为最后一个字段)

  • sub(/^[^ ]+ */,"") - 删除包含以下空格的第一个字段

输出:

male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50 0.354167
male typ_angina 0.792453 0.328767 f left_vent_hyper 0.564885 no 0.677419 down 0 reversable_defect <50 0.625
male non_anginal 0.433962 0.134703 f left_vent_hyper 0.641221 no 0.483871 flat 0 normal >50_1 0.645833
female asympt 0.481132 0.413242 f left_vent_hyper 0.572519 yes 0.16129 flat 0 reversable_defect >50_1 0.666667
male typ_angina 0.509434 0.269406 f left_vent_hyper 0.816794 no 0.129032 up 0.666667 normal <50 0.270833

答案 1 :(得分:4)

Perl对于文本操作非常方便:

perl -lane 'push @F, shift @F; print "@F"' file

答案 2 :(得分:4)

由于这是对单个行的简单替换,因此对于sed来说这是一个完美的工作:

$ sed 's/\([^ ]*\) \(.*\)/\2 \1/' file
male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50 0.354167
male typ_angina 0.792453 0.328767 f left_vent_hyper 0.564885 no 0.677419 down 0 reversable_defect <50 0.625
male non_anginal 0.433962 0.134703 f left_vent_hyper 0.641221 no 0.483871 flat 0 normal >50_1 0.645833
female asympt 0.481132 0.413242 f left_vent_hyper 0.572519 yes 0.16129 flat 0 reversable_defect >50_1 0.666667
male typ_angina 0.509434 0.269406 f left_vent_hyper 0.816794 no 0.129032 up 0.666667 normal <50 0.270833

答案 3 :(得分:3)

在awk中。直截了当,找到第一个空格,“在它之后和之前打印:

$ awk '{
    match($0," ")                                         # find space
    print substr($0,RSTART+RLENGTH),substr($0,1,RSTART)   # print around it
}' file
male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50 0.354167 
male typ_angina 0.792453 0.328767 f left_vent_hyper 0.564885 no 0.677419 down 0 reversable_defect <50 0.625 
...

或带有字段的播放:将第一个字段存储到t,然后从第一个字段开始将其替换为下一个字段。将最后一个字段替换为t

$ awk '{t=$1;for(i=1;i<NF;i++)$i=$(i+1);$NF=t}1' file
male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50 0.354167
...

说明:

$ awk ' 
{
    t=$1               # store 1st to t
    for(i=1;i<NF;i++)  # iterate all but the last field
        $i=$(i+1)      # replacing with the next
    $NF=t              # then the last is replaced with t
}1                     # output
' file

答案 4 :(得分:2)

以下awk将解决您的问题。

解决方案1:

awk '{for(i=2;i<=NF;i++){printf("%s%s",$i,i==NF?" "$1"\n":" ")}}'   Input_file

输出如下。

male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50 0.354167

说明: 遍历从第2个字段开始到NF(字段总数)值的所有字段。这里我使用printf来打印值,所以有两个字符串,我打算打印第一个是偏离课程字段的值,第二个是检查变量i的值是否等于NF意味着我们达到了到最后一个字段然后打印空间第一个字段和新行(根据OP的请求)否则(如果我的值不等于NF)则打印简单空格。

编辑:我现在运行我的命令来完成Input_file,看起来很好,因为输出如下。

awk '{for(i=2;i<=NF;i++){printf("%s%s",$i,i==NF?" "$1"\n":" ")}}'  Input_file
male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect <50 0.354167
male typ_angina 0.792453 0.328767 f left_vent_hyper 0.564885 no 0.677419 down 0 reversable_defect <50 0.625
male non_anginal 0.433962 0.134703 f left_vent_hyper 0.641221 no 0.483871 flat 0 normal >50_1 0.645833
female asympt 0.481132 0.413242 f left_vent_hyper 0.572519 yes 0.16129 flat 0 reversable_defect >50_1 0.666667
male typ_angina 0.509434 0.269406 f left_vent_hyper 0.816794 no 0.129032 up 0.666667 normal <50 0.270833