sort part of a file
I think what you're after is something like these:
Method #1: using head & tail
$ (head -n 2 sample.txt; tail -n +3 sample.txt | sort -t' ' -nk2) > a.tmp && mv a.tmp sample.txt
Nome Note
------------
Mehdi 0
Shnou 5
Others 10
Sunday 20
This takes the first line of the text file, then tails everything after the first 2 lines which is then sorted.
Method #2: just using head
$ (head -n 2; sort -t' ' -nk2) < sample.txt > a.tmp && mv a.tmp sample.txt
Nome Note
------------
Mehdi 0
Shnou 5
Others 10
Sunday 20
Takes the text file as input, displays just the first line, sort the rest.
It's typically not a good idea to edit files in place. It's possible, but better to use an intermediate file.
Method #3: Doing #2 without an intermediate file
Stealing the idea from @StephaneChazelas you could do the following using the "1<>" notation to open a file for reading & writing, and the improvements he suggested with the sort
command.
$ (head -n 2; sort -nk2) < sample.txt 1<> sample.txt
Nome Note
------------
Mehdi 0
Shnou 5
Others 10
Sunday 20
To overwrite the file in place, you can do:
{
head -n 2 &&
sort -k2n
} < the-file.txt 1<> the-file.txt
That works because sort
has read its input fully before it starts to write its output, so it's fine to write to the file it is reading from. Also its ouput is the same size as its input, so no need to truncate the file in the end.
Note that if you use -t' '
instead of the default separator, each space character in the input would make a new field, so for instance in:
a 10
b 2
(with a space before a
and 2 spaces after b
), -t' ' -nk2
(remember -k2
is for from field 2 to end of line, while -k2,2
is field 2 only) would compare "a 10"
to " 2"
numerically, while -nk2
alone would compare " 10"
to " 2"
numerically (and numerical comparison ignores leading blanks).