1

Sometimes I want to sort stuff, but not the header. So, for example, when I list loaded modules in Apache, there is a 1-line header that gets included in the sort:

 $ /usr/local/apache2/bin/apachectl -M | sort

 alias_module (shared)
 asis_module (static)
 cache_disk_module (static)
 cache_module (static)
 core_module (static)
 data_module (static)
 env_module (shared)
 ext_filter_module (static)
 file_cache_module (static)
 filter_module (shared)
 headers_module (shared)
 heartbeat_module (static)
 heartmonitor_module (static)
 http_module (static)
 include_module (static)
 info_module (static)
Loaded Modules:
 log_config_module (shared)
 macro_module (static)
 mime_module (shared)
 mpm_event_module (static)
 ratelimit_module (static)
 reqtimeout_module (shared)
 setenvif_module (shared)
 so_module (static)
 ssl_module (static)
 status_module (shared)
 substitute_module (static)
 unixd_module (static)
 version_module (shared)
 watchdog_module (static)

I tried using the -b option, but that had no effect. In any case, ignoring leading spaces would just be a workaround anyway. What I really want to do is exclude N lines of header from the sort. How can I do that?

Tyler Durden
  • 5,631

3 Answers3

0

I figured out that this can be done just by using a numeric argument to head. Since the rest of the lines, except the head still get delivered to stdout, sort can receive the rest of the lines:

$ /usr/local/apache2/bin/apachectl -M | { head -1; sort; }

Put however many lines of header there are after head (here it is 1).

Tyler Durden
  • 5,631
  • 1
    with most head implementations (ksh93's head builtin being an exception), that won't work properly as head will read its input by block so typically read more than one line of the input. Try seq 10 | { head -1; sort; } for instance. – Stéphane Chazelas Jan 11 '18 at 15:58
  • @StéphaneChazelas It works fine on my generic Debian system. I can't get the seq thing to work, can you give a full example using my statement? – Tyler Durden Jan 11 '18 at 16:07
  • That will depend on how fast apachectl outputs the second and following lines. If it outputs them at the same time as the header (within the same write() system call) or before head has read the first line, then they will be eaten by head. line, or IFS= read -r line or ksh93's head builtin avoid the problem by reading the input one byte at a time and stop reading as soon as they see the delimiter of the first line. – Stéphane Chazelas Jan 11 '18 at 17:27
0

You can also use tail -n+3 to start on the third line, assuming the blank line was the second line of the output.

$ /usr/local/apache2/bin/apachectl -M | tail -n+3 | sort
  • The problem with this solution is that it doesn't print the header. – Tyler Durden Jan 11 '18 at 16:09
  • You are right. However, the following seems to work and I will edit my answer if allowed. – NomadMaker Jan 12 '18 at 01:01
  • I was wrong. I was trying to duplicate contents of /dev/stdin as it came out of apachectl and send it to both head and tail, and then recombine them to be piped to sort. I hate to say it, but I can't make head or tails of this. :) – NomadMaker Jan 12 '18 at 01:22
0
sed -n '1p' filename;sed -r "s/\s+//g" l.txt| sed '/^$/d' | sed -n '1!p'  | sort -n

sed -n '1p' filename ==>command will first display the Header line.

sed -r "s/\s+//g" l.txt| sed '/^$/d' | sed -n '1!p' | sort -n ==>it will print from 2nd line to end of file and sort it.

If you want to get it sorted from different line . You can just change the line number in command.

Let me know for any doubts.