在 awk 中使用空行分隔的记录和冒号分隔的字段
Using blank-line delimited records and colon-separated fields in awk
我希望能够使用 awk
中的文件,其中记录由空行分隔,每个字段由一个名称后跟一个冒号组成,一些可选的空格是 ignored/discarded,后跟一个值。例如
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
关联数组?
方法一
我们使用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
对于其他 awk,您可能需要一次删除一个数组元素,例如:
for (k in a) delete a[k];
我希望能够使用 awk
中的文件,其中记录由空行分隔,每个字段由一个名称后跟一个冒号组成,一些可选的空格是 ignored/discarded,后跟一个值。例如
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
关联数组?
方法一
我们使用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
对于其他 awk,您可能需要一次删除一个数组元素,例如:
for (k in a) delete a[k];