I have a csv file with a general format
date,
2013.04.04,
2013.04.04,
2012.04.02,
2013.02.01,
2013.04.05,
2013.04.02,
a script I run will add data to this file which will not necessarily be in date order. How can I sort the file into date order (ignoring the header) and overwrite the existing file rather than writing to STDOUT
I have used awk
awk 'NR == 1; NR > 1 {print $0 | "sort -n"}' file > file_sorted
mv file_sorted file
Is there a more effective way to do this without creating an additional file and moving?
How to sort by number. To sort by number pass the -n option to sort . This will sort from lowest number to highest number and write the result to standard output. Suppose a file exists with a list of items of clothing that has a number at the start of the line and needs to be sorted numerically.
Using options in the sort command can also be used to sort numerically. SORT command sorts the contents of a text file, line by line. sort is a standard command-line program that prints the lines of its input or concatenation of all files listed in its argument list in sorted order.
Sort a File Numerically To sort a file containing numeric data, use the -n flag with the command. By default, sort will arrange the data in ascending order. If you want to sort in descending order, reverse the arrangement using the -r option along with the -n flag in the command.
Sorting numbers is extremely simple on Unix systems; just use the -n option with your sort commands.
You can do the following:
sort -n -o your_file your_file
-o
defines the output file and is defined by POSIX, so it is safe to use (no original file mangled).
Output
$ cat s
date,
2013.04.04,
2013.04.04,
2012.04.02,
2013.02.01,
2013.04.05,
2013.04.02,
$ sort -n -o s s
$ cat s
date,
2012.04.02,
2013.02.01,
2013.04.02,
2013.04.04,
2013.04.04,
2013.04.05,
Note that there exists a race condition if the script and the sorting is running at the same time.
If the file header sorts before the data, you can use the solution suggested by fedorqui as sort -o file file
is safe (at least with GNU sort, see info sort
).
Running sort
from within awk
seems kind of convoluted, another alternative would be to use head
and tail
(assuming bash shell):
{ head -n1 file; tail -n+2 file | sort -n; } > file_sorted
Now, about replacing the existing file. AFAIK, You have two options, create a new file and replace old file with new as you describe in your question, or you could use sponge
from moreutils
like this:
{ head -n1 file; tail -n+2 file | sort -n; } | sponge file
Note that sponge
still creates a temporary file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With