简体   繁体   中英

Linux - numerical sort then overwrite file

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM