我有一个转发 DNS 区域文件的摘录,我想按 IP 地址升序对其进行排序。在将其标记为重复之前,请先阅读一会儿,因为这不是关于对 IP 地址进行排序(sort -k5V
将解决这个问题)。
以下是数据示例:
esx01.example.com. 3600 IN A 10.1.1.212
ilo01.example.com. 3600 IN A 10.1.1.211
nas01.example.com. 3600 IN A 10.1.1.101
pc001.example.com. 1200 IN A 10.1.1.42
pc002.example.com. 1200 IN A 10.1.1.52
pc003.example.com. 1200 IN A 10.1.1.29
在这种特定情况下,我知道我可以仅按最后一个八位字节进行排序,因此这应该是sort
.
手册页确认我-k
不仅可以使用字段,还可以使用该字段内的偏移量以及n
数字修饰符
KEYDEF
是F[.C][OPTS][,F[.C][OPTS]]
开始和结束位置,其中F
是字段编号和C
字段中的字符位置;两者都是原点 1,停止位置默认为线的末尾。如果 -t 和 -b 均无效,则字段中的字符从前面的空格的开头开始计数。OPTS
是一个或多个单字母排序选项 [bdfgiMhnRrV
],它会覆盖该键的全局排序选项。
最后一个八位字节方便地从第五个字段中的字符偏移量 8 开始,所以我的理解是这个命令应该足够了:
sort -k5.8n /tmp/axfr.10.1.1
但是,这根本不会对我的数据进行排序。根据经验,我发现我需要从现场位置开始15按预期按升序对数据进行排序:
sort -k5.15n /tmp/axfr.10.1.1
pc003.example.com. 1200 IN A 10.1.1.29
pc001.example.com. 1200 IN A 10.1.1.42
pc002.example.com. 1200 IN A 10.1.1.52
nas01.example.com. 3600 IN A 10.1.1.101
ilo01.example.com. 3600 IN A 10.1.1.211
esx01.example.com. 3600 IN A 10.1.1.212
为什么?
答案1
使用该sort --debug
选项来获取一些线索:
$ echo 'esx01.example.com. 3600 IN A 10.1.1.212' |
sort --debug -k5.8n
sort: using simple byte comparison
sort: leading blanks are significant in key 1; consider also specifying 'b'
sort: key 1 is numeric and spans multiple fields
esx01.example.com. 3600 IN A 10.1.1.212
____
它在排序字段下划线。这不是你所期望的。您需要-b
,因为排序从上一个字段的末尾开始计算列(手册页:如果 -t 和 -b 均无效,则字段中的字符从前面的空格的开头开始计数):
$ ... | sort --debug -b -n -k5.8
sort: using simple byte comparison
sort: key 1 is numeric and spans multiple fields
esx01.example.com. 3600 IN A 10.1.1.212
___
需要-n
分开:
$ ... | sort --debug -b -k5.8n
sort: using simple byte comparison
sort: leading blanks are significant in key 1; consider also specifying 'b'
sort: key 1 is numeric and spans multiple fields
sort: option '-b' is ignored
esx01.example.com. 3600 IN A 10.1.1.212
____
或b
给定的n
:
$ ... | sort --debug -k5.8nb
sort: using simple byte comparison
sort: key 1 is numeric and spans multiple fields
esx01.example.com. 3600 IN A 10.1.1.212
___
答案2
当排序(或任何东西)的字段规范失去动力,变得难以构建、破译和调试时,预处理数据可以更高效、更清晰:
awk -F. '{print $NF"\t"$0}' | sort -snk1,1 | cut -f2-