【问题标题】:Flip first and last columns using awk [duplicate]使用awk翻转第一列和最后一列[重复]
【发布时间】:2014-03-23 22:33:44
【问题描述】:
#!/bin/bash
  awk '{
           a[i++] = $1;
           a2[k++] = $NF;
          }
         END{
           for(j = 1; j<=NR; j++){
           printf"%d ",a[NR-j];
                 for(m = 2; m<NF;m++){
                   printf"%d ",$m;
                }
          printf"%d\n", a2[NR-j];
          }
        }'

我正在尝试翻转任何大小矩阵中的第一列和最后一列。目前它正在翻转第一列和最后一列,但打印最后一行的中间列值

【问题讨论】:

  • 不想重新排列列或移动它们.. 想反转外部列的顺序
  • @user3453452 发布一些示例输入数据和您的预期输出。
  • 为了消除歧义,您会提供示例输入和相应的所需输出吗?
  • @user3453452:重新排列或移动列只是您想要实现的更一般的情况。

标签: bash awk


【解决方案1】:

要翻转每行的第一列和最后一列(大小不同),您可以尝试以下操作:

[ ~]$ cat test.txt 
1 2 3 4 5
1 2 3
1 2 3 4 5 6
[ ~]$ awk '{tmp=$1; $1=$NF; $NF=tmp; print}' test.txt
5 2 3 4 1
3 2 1
6 2 3 4 5 1

【讨论】:

    【解决方案2】:

    在 AWK 中,字段也可以出现在赋值的左侧:

    seq 20 | paste -s -d ' ' -
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
    
    seq 20 | paste -s -d ' ' - | awk '{ x=$1; $1=$NF; $NF=x; print }'
    20 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1
    

    【讨论】:

      【解决方案3】:

      Awk 的END 部分用于处理您遍历整个文件之后。例如:

      awk ' BEGIN { total = 0 }
            END   { print "The total of column 1 is " total}
            {
                total += $1
                print $0
            }'  file.txt
      

      在这里,我有一个 BEGINEND 子句。 BEGIN 子句在处理我的文件之前运行,基本上将变量 total 初始化为 0。(不是必需的,但我想要一些示例)。

      END 子句在我处理完文件中的所有行之后运行。它打印出我在每一行中读取时正在计算的total 变量的数量。我的程序的主要部分(这是最后一个子句),只需将列 $1 添加到总计并打印出该行。

      您想要做的是在您阅读该行时更改该行的打印方式。您希望最后一列(无论是什么)作为第一列打印,第一列作为最后一列打印。 NF 变量告诉您​​您拥有的字段数:

      awk '{
          for ( count = 1; count <= NF; count++ ) {
              if ( count == 1 ) {
                  printf $NF "  "
              }
              else if ( count == NF ) {
                  print $1
                  continue
              }
              else {
                  printf $count "  "
              }
          }
      }' test.txt
      

      在这里,我只有我的主句。我有一个for 循环,它从每一行的第一到最后一个 field 循环(请记住,每一行都由我的 awk 语句处理。如果 count 为 1,我在我的第一个字段,然后打印最后一个字段 ($NF)。如果我的 count 等于该行上的字段数,我打印第一个字段 ($1)。否则,我打印出该字段自己。

      这不是可以产生的最紧凑的awk 形式,但它很容易理解。

      有效吗?

      这是我的测试文件:

      one two three four five six
      alpha beta gamma
      bob carol ted alice
      uno dos tres quatro cinco ses
      alpha bravo charlie delta echo
      apple banana carrot darren eggplant fennel
      

      这是输出:

      six  two  three  four  five  one
      gamma  beta  alpha
      alice  carol  ted  bob
      ses  dos  tres  quatro  cinco  uno
      echo  bravo  charlie  delta  alpha
      fennel  banana  carrot  darren  eggplant  apple
      

      【讨论】:

        【解决方案4】:

        当特定行消失时,awk 不再记住其内容,除非您明确存储它们。因此,在END 块中,$m 表示最后一行中的第 m 个值,并且您没有将前面所有行的第 m 个值存储在任何地方。

        看起来您必须将整个矩阵存储在内存中才能使其工作,或者以某种方式通过两次而不是一次遍历文件来完成这项工作。

        【讨论】:

          猜你喜欢
          • 2015-11-04
          • 2014-01-27
          • 1970-01-01
          • 2023-02-04
          • 1970-01-01
          • 2014-03-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多