sorting - gawk 和 PROCINFO 在对较长长度的字符串进行排序时无法按预期工作
问题描述
假设我有一个简单的小字符串文件,我想按行长排序:
$ cat file1
123
2
45
12345
123456789
1
我可以编写一个gawk
脚本,使用一个函数对这些字符串进行排序,并且PROCINFO["sorted_in"]
:
$ gawk 'function cmp_len(i1, v1, i2, v2) {
return length(v1) - length(v2)
}
NR==FNR{arr[$0]; next}
END{PROCINFO["sorted_in"] = "cmp_len"
for (e in arr) print e
}
' file1
1
2
45
123
12345
123456789
完美的!
但是现在假设我在该文件中添加了一些更长的字符串:
$ cat file2
123
2
45
xyxyxyxyxyyxyxyxyxyxyyxyxyxxyxyxyxyyxyxyxyxyyx
12345
56565656565656565665656566565656656565656
123456789
1
它打破了:
$ gawk 'function cmp_len(i1, v1, i2, v2) {
return length(v1) - length(v2)
}
NR==FNR{arr[$0]; next}
END{PROCINFO["sorted_in"] = "cmp_len"
for (e in arr) print e
}
' file2
123456789
56565656565656565665656566565656656565656
1
2
45
123
12345
xyxyxyxyxyyxyxyxyxyxyyxyxyxxyxyxyxyyxyxyxyxyyx
它确实以这种方式正常工作:
$ awk '{ print length()"\t"$0}' file2 | sort -n | cut -f2
# expected output by length...
但这使我正在编写的脚本更加困难。
任何想法为什么PROCINFO
在这个例子中不使用更长的字符串?
解决方案
从手册:
这里,“i1”和“i2”是索引,“v1”和“v2”是被比较的两个元素的对应值。
您的比较函数是比较数组的值,而不是索引。并且值始终是空字符串,因此函数始终返回 0。将其更改为
function cmp_len(i1, v1, i2, v2) {
return length(i1) - length(i2)
}
你会得到你想要的订单。或者更好的是,缓存长度并使用内置比较,因为存储了一个有意义的值:
gawk '
NR==FNR { arr[$0] = length($0) }
END {
PROCINFO["sorted_in"] = "@val_num_asc"
for (e in arr) print e
}
' file1
推荐阅读
- redis - redis 保存导致集群故障转移
- firebase - Flutter Firestore如何在提交之前检查Firestore中的现有数据作为用户类型
- java - 如何设置 Spring Security 以返回 401 而不是登录页面
- python - 如何有效地查看元素是否在元组列表中
- python - 已解决如何将数字单词转换为电话号码初学者样式?
- node.js - Use prefix for route routes in express
- python - 如何在一分钟内多次联系一个api?
- google-chrome-extension - Chrome Devtools Network API - 如何识别最后的网络请求
- python - 如何在 Django 中每天 24 小时循环运行机器人?
- python - 如何将数据框从字典导出到 Excel