2

a.txt 的内容

name age
alice 21
ryan 30

#test.sh
nf=`awk '{print NF; exit}' a.txt`
for((i=1;i<=$nf;i++))
{
    awk '{print $i}' ./a.txt
}

我期望的结果是每列打印,但实际结果是打印所有内容两次。

我的预期输出是

name
alice
ryan
age
21
30

实际输出为

name age
alice 21
ryan 30
name age
alice 21
ryan 30

4

5 回答 5

2

这可以单独完成awk,请尝试以下操作;使用您的演示样本编写和测试。

awk -v tot="0" '
{
  for(i=1;i<=NF;i++){
    arr[i]=(arr[i]?arr[i] ORS:"")$i
  }
  tot=(tot>NF?tot:NF)
}
END{
  for(i=1;i<=tot;i++){
    print arr[i]
  }
}
' Input_file

说明:为上述添加详细说明。

awk -v tot="0" '          ##Starting awk program from here, setting tot to 0 here.
{
  for(i=1;i<=NF;i++){     ##Traversing through all fields here.
    arr[i]=(arr[i]?arr[i] ORS:"")$i  ##Creating arr with index of i and keep appending current field value in it.
  }
  tot=(tot>NF?tot:NF)     ##Creating tot by seeing current total number of fields, to get highest NF value here.
}
END{                      ##Starting END block of this program from here.
  for(i=1;i<=tot;i++){    ##Running for loop from i=1 to till tot value here.
    print arr[i]          ##Printing array with index of i here.
  }
}
' Input_file              ##Mentioning Input_file name here.
于 2021-06-14T06:12:23.713 回答
2

如果您更喜欢节省资源/内存,则使用另一种gawk不保存 inside的方法:array

awk '
    FNR==1 && ++fcount<NF{
        delete ARGV[fcount]
        ARGV[fcount+1]=FILENAME
        ARGC++
     }
     {
        print $(fcount)
     }
    ' file

结果:

$ cat file 
name age
alice 21
ryan 30


$ awk 'FNR==1 && ++fcount<NF{delete ARGV[fcount];ARGV[fcount+1]=FILENAME;ARGC++}{print $(fcount)}END{for(i in ARGV)print i,ARGV[i]}' file
name
alice
ryan
age
21
30
于 2021-06-14T07:08:33.950 回答
1

因为你$i只对 可见bash,对 不可见awk。您需要将其传递到您的 awk 脚本中:

awk -v i=$i '{print $i}' ./a.txt

-v选项允许您将变量传递到awk. i=$i意味着$i您的 awk 脚本中的 将$i在您的 bash 中。

如果允许使用其他工具,您可以尝试

cut -f $i a.txt

作为一个更简单的候选。

于 2021-06-14T04:43:04.560 回答
1

您不需要 shell 循环,只需 1 次调用 awk。在每个 Unix 机器上的任何 shell 中使用任何 awk:

$ cat tst.awk
{
    for (i=1; i<=NF; i++) {
        vals[NR,i] = $i
    }
}
END {
    for (i=1; i<=NF; i++) {
        for (j=1; j<=NR; j++) {
            print vals[j,i]
        }
    }
}

$ awk -f tst.awk a.txt
name
alice
ryan
age
21
30

或者,如果您愿意,可以将 GNU awk 用于数组数组:

$ cat tst.awk
{
    vals[NR][1]
    split($0,vals[NR])
}
END {
    for (i=1; i<=NF; i++) {
        for (j=1; j<=NR; j++) {
            print vals[j][i]
        }
    }
}

$ awk -f tst.awk a.txt
name
alice
ryan
age
21
30
于 2021-06-14T18:41:24.807 回答
0

awk不使用任何数组的情况下,您可以获得预期的输出:

awk  'NR==FNR{print $1;next}{print $2}' file file
name
alice
ryan
age
21
30
于 2021-06-14T09:07:10.173 回答