我希望能够处理awk
中的文件,其中记录由空行分隔,每个字段由一个名称后跟一个冒号组成,一些可选的空格可以忽略/丢弃,然后是一个值。 E.g。
Name: Smith, John
Age: 42
Name: Jones, Mary
Age: 38
Name: Mills, Pat
Age: 62
我了解我可以使用RS=""
让awk
将空白行理解为记录分隔符,并FS="\n"
将字段正确分割。但是,我想创建一个name
→value
对数组,我可以用它来进一步处理表单
if a["Age"] > 40 {print a["Name"]}
订单通常一致,但由于它会被转储到关联数组中,因此传入的订单不应该重要或被认为是一致的。
如何将数据转换为awk
关联数组,并且操作最少?
答案 0 :(得分:3)
我们使用split
将每个字段分成两部分:键和值。从这些中,我们创建了关联数组a
:
$ awk -F'\n' -v RS= '{for (i=1;i<=NF;i++) {split($i,arr,/: /); a[arr[1]]=arr[2];} if (a["Age"]+0>40) print a["Name"];}' file
Smith, John
Mills, Pat
在这里,我们在分割字段冒号或换行符。然后,我们知道奇数字段是键,偶数字段是值:
$ awk -F':|\n' -v RS= '{for (i=1;i<=NF;i+=2) {a[$i]=$(i+1);} if (a["Age"]+0>40) print a["Name"];}' file
Smith, John
Mills, Pat
是否有可能任何记录都会遗漏某个值?如果是这样,我们应该清除每条记录之间的数组a
。在GNU awk中,这很容易。我们只需添加一个删除语句:
awk -F':|\n' -v RS= '{delete a; for (i=1;i<=NF;i+=2) {a[$i]=$(i+1);} if (a["Age"]+0>40) print a["Name"];}' file
对于其他awks,您可能需要一次删除一个元素,如:
for (k in a) delete a[k];