如何将第一列移动到最后一列在UNIX?

这是一个文本文件中的数据。

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命令?

Perl在文本处理上很方便:

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

简短的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 

由于这是一个简单的替代个人行,这是一个完美的工作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 

在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 

以下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来打印值,所以有2个字符串,我正在寻找打印第一是偏离球场的价值,第二是检查变量我的价值是否等于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