1

I want a command sorth (=sort with header) that is like the unix sort command with all the command-line options, but also able to avoid headers. I tried the following ways:

sorth (attempt 1):

#!/opt/local/bin/bash
head -n 1 $1 && $1 -n +2 table | sort

The problem with this is 1) that I don't know how to distinguish between the target file $1 and any options in the sort command at the end of the 2nd line, and (2) it seems inefficient to access the file twice before you even get to the sort command.

Then I tried (using this, modifying @Dave's answer to allow command line options)

sorth (attempt 2):

#!/opt/local/bin/bash
gawk -v options="$1"  '
BEGIN {FS=",";OFS=","} 

NR==1 {print;next}

{print| "sort $options" }' 

But this doesn't work either, probably also because I haven't distinguished between the sort options and the target file.

I want the command to be flexible to use a target file or piped STDIN.

How can I do this?

What would be even cooler is to include a new option --retain-headers under the existing sort command. But I suspect that's way hard and dangerous.

Tim
  • 291
  • 2
  • 17
  • 1
    The answers [here](https://unix.stackexchange.com/questions/11856/sort-but-keep-header-line-at-the-top) are useful for the pipe case, but not for the file case. It might be easiest just to implement them, and then call `body sort --option1 --option2 < file` (using the [accepted answer](https://unix.stackexchange.com/a/11859/22975) there) whenever you want to run on a file. – Daniel H Sep 13 '17 at 15:09
  • @CharlesDuffy if you have time, I'd be interested in seeing your solution for reading input from stdin or a file and for handling passing the sort args to sort without the shell script having to parse them individually first. I can do it, but I suspect there's better practices... – Ed Morton Sep 13 '17 at 15:09

1 Answers1

1

GNU awk (gawk) has a sort function (POSIX awk does not), but I'm not sure you want it.

Here's a small, simple, and portable solution:

#!/bin/sh

read header
echo "$header"

sort "$@"

This needs to be piped or directed into. Arguments are passed just to the sort command-line utility. This lets you do e.g.

  • sorth -r < myfile
  • df -k | sorth -rnk4

 

This can also be done on the command line. Repeating those examples, we have:

  • { read h; echo "$h"; sort -r } < myfile
  • df -k | { read h; echo "$h"; sort -rnk4 }

I've also written a script called sortn that can accept arguments and an arbitrary number of lines for the header. It accepts all arguments from GNU sort.

Adam Katz
  • 14,455
  • 5
  • 68
  • 83
  • pretty good. It still doesn't accept `sorth myfile` ; it requires `sorth – Tim Sep 14 '17 at 07:35
  • 2
    Yes, that's what I meant by "This needs to be piped or directed into." Otherwise, you need to parse the arguments into options and input(s), which is nontrivial. I actually have a script that does this. I'll link to it once I actually get around to posting it to my github. – Adam Katz Sep 14 '17 at 15:45
  • 1
    I've modified my answer to link to my [sortn](https://github.com/adamhotep/misc-scripts/blob/master/sortn) script on Github. – Adam Katz Sep 24 '17 at 22:47