按字段内的字符字段位置进行数字排序

roa*_*ima 1 sort

我有一个转发 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
Run Code Online (Sandbox Code Playgroud)

在这种特定情况下,我知道我可以仅按最后一个八位字节排序,因此这应该是sort.

手册页确认我-k不仅可以使用字段,还可以使用该字段内的偏移量,以及n数字修饰符

KEYDEFF[.C][OPTS][,F[.C][OPTS]]开始和停止位置,其中F是字段编号和字段中C的字符位置;两者都是原点 1,停止位置默认为线的末端。如果 -t 和 -b 均无效,则字段中的字符从前一个空格的开头开始计数。OPTS是一个或多个单字母排序选项 [ bdfgiMhnRrV],覆盖该键的全局排序选项。

最后一个八位字节很方便地从第五个字段中的字符偏移量 8 开始,所以我的理解是这个命令应该足够了:

sort -k5.8n /tmp/axfr.10.1.1
Run Code Online (Sandbox Code Playgroud)

但是,这根本不会对我的数据进行排序。根据经验,我发现我需要从字段位置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
Run Code Online (Sandbox Code Playgroud)

为什么?

meu*_*euh 7

使用该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
                                                ____
Run Code Online (Sandbox Code Playgroud)

它在排序字段下划线。这不是你所期望的。您需要-b, 因为 sort 从前一个字段的末尾开始计算列数(手册页:如果 -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
                                                       ___
Run Code Online (Sandbox Code Playgroud)

-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
                                                ____
Run Code Online (Sandbox Code Playgroud)

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
                                                       ___
Run Code Online (Sandbox Code Playgroud)

  • gnu 的 `info sort` 表示 * 用“-k”指定的排序字段中的位置可能附加了任何选项字母“MbdfghinRrV”,在这种情况下,该特定字段不会继承全局排序选项。* (2认同)
  • @meuh - 是的,相同的信息页面确实声明“全局选项_由未指定任何特殊选项的关键字段继承_”因此`-bnk5.8`有效,因为关键字段没有自己的选项而`-bk5.8n` 不起作用,因为键字段已经有`n` 选项,所以`-b` 不会被继承。 (2认同)
  • 这是手册页中的相应文本,“OPTS”是一个或多个单字母排序选项 [`bdfgiMhnRrV`],_它覆盖该键的全局排序选项_。» 我想如果它说“覆盖_所有_全局排序选项...”,我就更有可能发现这一点。 (2认同)