这个AWK命令是如何保持数组元素顺序的?



这是一个RGB值列表,来自一个名为" colors.txt "的文件

255 222 0  
101 153 255  
255 153 0  
13  112 84  
13  112 84  
255 222 0  
13  112 84  
9   112 84  

我可以使用awk数组从

文件中获得5个唯一的RGB组合
awk '{arr[($1","$2","$3)]} END {for (i in arr) print i}' colors.txt

这给:

9,112,84  
255,222,0  
13,112,84  
255,153,0  
101,153,255  

注意,它们的顺序与它们在输入文件中的顺序不同。但是,这个命令

awk 'arr[($1","$2","$3)]++==0 {print ($1","$2","$3)}' colors.txt
255,222,0  
101,153,255  
255,153,0  
13,112,84  
9,112,84  

保留顺序。这究竟是如何工作的呢?我在这里找到了第二个命令版本。

只是为了好玩,你可以把它组合成一个笨拙的:

awk '!A[$1=$1,$2,$3]++' OFS=, file

这一行:

awk '{arr[($1","$2","$3)]} END {for (i in arr) print i}' colors.txt

在读取所有输入后打印散列,由于散列键不保持顺序,因此输出是相当任意的。

这个命令

:

awk 'arr[($1","$2","$3)]++==0 {print ($1","$2","$3)}' colors.txt

检查之前是否使用散列打印了相同的组合,但是,如果arr[($1","$2","$3)]为零,它立即打印输入。所以,没有秩序维持。它更像是直接打印。

perreal已经解释了为什么顺序是保留的,我想谈谈这个习语的一些细节:

  • 如果脚本中只有一个数组,我倾向于使用hashh来提醒自己它的类型。
  • 逗号分隔的数组下标已经在gawknawk中按预期工作,即h[$1,$2,$3]变为h[$1 SUBSEP $2 SUBSEP $3]SUBSEP默认值为340x1c
  • 我发现!h[...]++h[...]++==0更容易读,也许这只是我。
  • 我喜欢使用OFS而不是显式打印,即$1=$1; print而不是print ($1","$2","$3)

所有这些放在一起:

awk '!h[$1,$2,$3]++ { $1=$1; print }' OFS=',' colors.txt

最新更新