1

I am currently struggling at sorting data. I searched online and never saw any topics mentioning my issue...

I have files with unordered data like:

1
blank line
3
blank line
2

Which have a blank line in between values. When I use my script, it effectively sorts data but blank lines are on top and values on bottom, like :

blank line
blank line
1
2
3

I would like to have an output like:

1
blank line
2
blank line
3

which preserves the structure of the input.

The command I use is: sort -nk1 filename > newfile

How can I preserve the blank lines in the right places?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
spheex12
  • 29
  • 3
  • Fundamentally, `sort` works on lines in isolation. Each line is separate. It cannot keep the structure you want. You could do it with programs such as Perl, using its I/O to read the number and blank lines as a unit, and then sorting those units. But plain `sort` can't do the job on its own. – Jonathan Leffler May 20 '18 at 12:24
  • `grep . filename | sort -nk1 | sed G` maybe? – Mark Setchell May 20 '18 at 12:29
  • 1
    You can do the job with a Perl one-liner: `perl -e '$/ = "\n\n"; print foreach (sort { $a <=> $b } <>);' data` (where `data` is the file containing the spaced data). I wouldn't claim that is self-explanatory — it is anything but. It is fairly compact, though. – Jonathan Leffler May 20 '18 at 12:31

1 Answers1

3

Remove the empty lines, sort and add the empty lines again:

grep . filename | sort -nk1 | sed 's/$/\n/' > newfile

You can combine grep and sed

sort -nk1 filename | sed -n '/./ s/$/\n/p' > newfile

When you don't have an empty line after each data-line, you need to add some marker temporarily

tr '\n' '\r' < filename | 
  sed -r 's/([^\r]+)\r\r/\1\a\r/g;s/\r/\n/g' | 
  sort -nk1 | sed 's/\a/\n/g' > newfile
Walter A
  • 19,067
  • 2
  • 23
  • 43