3

In linux we can run sort command to sort file contents, but in my case I have the following file (THANKS.txt):

These people have contributed to OSN Envoy. We always try to keep this list updated and correct. 
If you notice that your name is not listed here, then feel free to contact us.

Ar Rakin
Peter Williamson
David Brook
Bill Natt

This file contains the list of the contributors of a software project.

I want to ONLY sort the names alphabetically using the sort command, any Idea?

3 Answers 3

3

With awk:

awk '
  NR == 1, NF == 0 {
    # print and skip all lines until the first blank
    # one (one where the Number of Fields is 0)
    print; next
  } 

  {print | "sort"} # pass the rest to sort
  ' < file

Replace NF == 0 with NR == 3 to stop at the third line instead of upon the first blank one.

To avoid having the rest go through both awk and sort (and also avoid the extra shell run by awk to interpret that trivial sort command line), you could do:

{
  sed '/[^[:blank:]]/!q'
  sort
} < file

Where sed quits upon finding the first line that does not (!) contain a non-blank character. Change to sed 3q to quit at the third line.

If the input is not seekable (like when it's coming from a pipe), sed will however not be able to leave the cursor within the file just after the delimiter of that line though, which means sort will miss the extra data that sed may have read (as it reads its input in largish blocks).

With the GNU implementation of sed, you can add the -u option for it to read its input one byte at a time so as not to read too much.

0
3

This would give you just the list of names, sorted:

sed '1,/^$/d' <THANKS.txt | sort

The pipeline uses sed to delete everything from the first line to the first empty line and passes the rest to sort for sorting. You may also use the line number of the empty line in place of the regular expression address /^$/, both above and in the other commands in this answer, if that is easier.

The initial part of the document could be had by

sed '1,/^$/!d' <THANKS.txt

That command essentially inverts the condition for the d command is sed so that it deletes the list of names rather than extracting the list of names.

Together, these two command could be used to solve the overall issue, creating the THANKS-sorted.txt output file:

{ sed '1,/^$/!d' <THANKS.txt; sed '1,/^$/d' <THANKS.txt | sort; } >THANKS-sorted.txt

Or, with nicer formatting:

{
    sed '1,/^$/!d' <THANKS.txt
    sed '1,/^$/ d' <THANKS.txt | sort
} >THANKS-sorted.txt

With the ed editor:

printf '%s\n' '1,/^$/ p' '+,$ w !sort' 'q' | ed -s THANKS.txt >THANKS-sorted.txt

This uses an ed editing script that looks like this:

1,/^$/ p
+,$ w !sort
q

This editing script outputs the first few lines, up until the first blank line. It then writes all lines from the next line after the blank line to the end of the document to sort, which outputs the sorted names.

The final q exits the editor, and the redirection at the end writes the resulting text to THANKS-sorted.txt.

0
0

If the head command doesn't close stdin (it doesn't on linux), try

{ head -n2; sort; } < file
These people have contributed to OSN Envoy. We always try to keep this list updated and correct. 
If you notice that your name is not listed here, then feel free to contact us.

Ar Rakin
Bill Natt
David Brook
Peter Williamson

If stdin is closed by head, try something like

{ read TMP; echo "$TMP"; read TMP; echo "$TMP"; sort; } < file
These people have contributed to OSN Envoy. We always try to keep this list updated and correct.
If you notice that your name is not listed here, then feel free to contact us.

Ar Rakin
Bill Natt
David Brook
Peter Williamson
3
  • 1
    It's not about head closing its input. Of course it closes its input as it terminates. But about it reading past the second newline character. All head implementations will likely read past the second newline as they read by blocks, but POSIX compliant ones will seek back to just after that newline character if the input is seekable. Commented Mar 4, 2022 at 12:58
  • @StéphaneChazelas great comment. I was wondering why cat file | ( head -n2; sort;) did not work but ( head -n2; sort;) < file did. Commented Mar 4, 2022 at 13:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .