awk 中的拆分不打印数组值

awk 中的拆分不打印数组值

我有一个字符串 tstArr2 ,其中包含以下内容

'3 5 8'

现在在 awk 中我想解析一个平面文件

test my array which array is better array

INDIA USA SA NZ AUS ARG GER BRA
US AUS INDIA ENG NZ SRI PAK WI BAN NED IRE

仅在这些编号的列中。我尝试了以下方法

awk -vA="$tstArr2" 'BEGIN{split(A,B," ");} {if(NR>1){for(i=1; i<= length(B); i++){printf "%s ",B[i]}}print " "}' testUnix3.txt

但它说

awk: Cannot read the value of  B. It is an array name.

The input line number is 2. The file is testUnix3.txt.
The source line number is 1.

我缺少什么?如果我尝试以下操作

awk -vA="$tstArr2" 'BEGIN{split(A,B," ");} {if(NR>1){for(i in B){printf "%s ",$B[i]}}print " "}' testUnix3.txt

它打印输出,但它们不按顺序排列。我希望它们井然有序。请解释。期望的输出:

 SA AUS BRA

 INDIA NZ WI

答案1

POSIX 定义长度inawk是一个字符串函数,参数作为字符串。使用length数组作为参数是未指定的行为。

在一些awk类似的实现中gawk(版本 >= 3.1.6),OS X 版本的 AWK,您可以使用length数组作为参数,它将返回数组中的元素数量。

数组 inawk是关联数组,循环关联数组并不能保证任何顺序。在这种情况下,您可以利用分裂函数,它返回字段的数量以获取数组的数量元素。

POSIXly,你可以尝试:

$ awk -vA="$tstArr2" '
  BEGIN{n = split(A,B," ");}
  {
    if(NR > 1) {
      for(i = 1;i <= n;i++) {
        printf "%s ",$B[i];
      }
    }
    print " ";
  }
' file

SA AUS BRA  
INDIA NZ WI

答案2

(对于非 GNU awk,请参阅 @cuonglm 的回答。)

以此作为测试文件:

$ cat testUnix3.txt 
test my array which array is better array

INDIA USA SA NZ AUS ARG GER BRA
US AUS INDIA ENG NZ SRI PAK WI BAN NED IRE

此代码选择第 3、5 和 8 列:

$ tstArr2='3 5 8'
$ awk  -vA="$tstArr2" 'BEGIN{split(A,B," ");} NR>1{for(i=1; i<= length(B); i++) printf "%s ",$B[i]; print "";}' testUnix3.txt

SA AUS BRA 
INDIA NZ WI 

以上是用 GNU 测试的awk

awk循环和顺序

awk具有关联数组。作为格雷莫尔 awk 教程 解释:

关联数组有一个小问题,特别是当您使用为了输出每个元素的命令:您无法控制输出的顺序。

for(i in B)这就是为什么您引用的其他使用循环的代码有时可能会乱序打印列的原因。

GNU awk 有一个扩展来解决这个问题:

$ gawk -vA="$tstArr2" 'BEGIN{split(A,B," "); PROCINFO["sorted_in"]="@ind_num_asc"} {if(NR>1){for(i in B){printf "%s ",$B[i]}print " "}}' testUnix3.txt

SA AUS BRA  
INDIA NZ WI  

通过设置PROCINFO["sorted_in"]="@ind_num_asc",索引将按数字升序循环。这个 GNU 扩展已记录在案这里

答案3

使用如此强大的仪器来awk完成如此简单的任务会产生很大的开销:

tstArr2='3,5,8'
tail -n+2 testUnix3.txt | cut -d' ' -f"$tstArr2"

相关内容