【问题标题】:How to move first column to last column in unix?如何在unix中将第一列移动到最后一列?
【发布时间】:2017-10-03 14:22:07
【问题描述】:

这是文本文件中的数据。

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

【问题讨论】:

    标签: linux bash unix awk


    【解决方案1】:

    在 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
    

    【讨论】:

      【解决方案2】:

      短 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
      

      【讨论】:

      • 您也可以使用$(NF+1) = $1 将第一个字段附加到末尾。
      【解决方案3】:

      由于这是对单个行的简单替换,因此它是 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
      

      【讨论】:

        【解决方案4】:

        Perl 对文本操作很方便:

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

        【讨论】:

          【解决方案5】:

          遵循 awk 将解决您的问题。

          解决方案一:

          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 个字符串,第一个是偏离课程字段的值,第二个是检查变量 i 的值是否等于 NF 意味着我们到达最后一个字段,然后打印空间第一个字段和新行(根据 OP 的要求)否则(如果 i 的值不等于 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
          

          【讨论】:

          • 数值在下一行打印出来 `male atyp_angina 0.066038 0.1621 t normal 0.648855 no 0 up 0 reversable_defect
          • @PrinceH,您能否尝试我的第二个解决方案,如果这对您有帮助,请告诉我?
          • @RavinderSingh13 不一样。这是来自 col 2-14 [new line] col1 [new line] | 的输出第 1 行第 2 行等我在 Windows 10 上使用 Linux bash shell
          • @EdMorton,明白了,先生,我现在收回我的话:)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-07
          • 2021-01-19
          • 2022-06-28
          • 2011-12-08
          • 2010-12-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多