1

I have an extract from a forward DNS zone file, which I want to sort by ascending IP address. Before you mark this as a duplicate, please read on a short while, because this isn't about sorting IP addresses as such (sort -k5V would address that).

Here is a sample of the data:

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

In this specific case I know I can sort by just the last octet, so this should be a straightforward application of sort.

The man page confirms that I can use -k with not only a field but also an offset within that field, and with an n numeric modifier

KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where F is a field number and C a character position in the field; both are origin 1, and the stop position defaults to the line's end. If neither -t nor -b is in effect, characters in a field are counted from the beginning of the preceding whitespace. OPTS is one or more single-letter ordering options [bdfgiMhnRrV], which override global ordering options for that key.

The last octet conveniently starts at character offset eight within the fifth field, so my understanding is that this command should suffice:

sort -k5.8n /tmp/axfr.10.1.1

However, this does not sort my data at all. Empirically I find I need to start at field position 15 to sort this data in ascending numeric order as expected:

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

Why?

  • 2
    GNU sort's -V option is useful to sort quad-decimal IPv4 addresses. – Stéphane Chazelas Nov 16 '17 at 16:45
5

Use the sort --debug option to get some clues:

$ 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
                                                ____

It is underlining the sort field. It isn't what you expected. You need -b, as sort counts columns from the end of the previous field (man page: If neither -t nor -b is in effect, characters in a field are counted from the beginning of the preceding whitespace):

$ ... | 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
                                                       ___

The -n needs to be separate:

$ ... | 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
                                                ____

or the b given with the 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
                                                       ___
  • Why does sort --debug -b -k5.8n warn that option '-b' is ignored? – roaima Nov 16 '17 at 16:07
  • It may have to do with compatibility with older versions. info sort for gnu sort says: According to POSIX, '-n' no longer implies '-b', so perhaps n in -k used to undo -b. – meuh Nov 16 '17 at 16:19
  • Mmm. sort -b -k5.10 is permitted, but sort -b -k5.10n is not. And for my data set sort -nb -k5.10 complains that, sort: key 1 is numeric and spans multiple fields. The whole concept of a sort field beginning with the field's preceding whitespace doesn't make any sense to me whatsoever, though. – roaima Nov 16 '17 at 16:36
  • 2
    gnu's info sort says A position in a sort field specified with '-k' may have any of the option letters 'MbdfghinRrV' appended to it, in which case no global ordering options are inherited by that particular field. – meuh Nov 16 '17 at 16:49
  • 2
    @meuh - yeah, the same info page does state that "the global options are inherited by key fields that do not specify any special options of their own" so -bnk5.8 works because the key field has no options of its own whereas -bk5.8n doesn't work since the key field already has the n option so -b isn't inherited. – don_crissti Nov 16 '17 at 16:56
0

When sort's (or anything's) field specs are running out of steam, getting hard to construct and decipher and debug, it can be more productive and clearer to preprocess the data:

awk -F. '{print $NF"\t"$0}' | sort -snk1,1 | cut -f2-
  • 1
    That's true, but it doesn't address the question I'm asking. (Which is not how to sort the data, but why sort doesn't behave as I expect.) – roaima Nov 16 '17 at 16:38
  • I've found that people, me included, will often enough attempt a bad solution to a problem and ask for help implementing their solution rather than fixing their problem. So it is here: your question is about how to do the wrong thing. Even once you get your index right your code will still be awfully fragile. – jthill Nov 16 '17 at 22:26
  • The best solution for the sorting task turns out to be sort -k5V, but the question isn't about how to sort IP addresses, it's why sort wasn't working the way I expected. My sample data happened to be the output from dig axfr... but it could equally have been from some other source. I had hoped my second sentence of the question would have made that quite clear; I've extended that even more explicitly, now. – roaima Nov 16 '17 at 22:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.