I was looking at this question and I wondered if the following could be done from terminal. I did it in python, just want to see if it could be done from terminal, bash scripting or whatever.
Suppose I have a file that looks like so:
2,4,5,14,9
40,3,5,10,1
could it be sorted like so, by rows (lines)
2,4,5,9,14
1,3,5,10,40
or is it too complicated? I did it using python, I just want to know if it could be done so next time I might not use python. What I have done, is creating lists and sorting them.
This should do about what you're looking for. It will read a file (test.txt) and create an output file (sorted.txt) with the sorted lines in the same order as they appear in the original file.
Here's another Perl approach:
And another shell/coreutils one (though personally, I prefer steeldriver's excellent answer which uses the same idea):
The only real difficulty in doing what you want using command-line scripting is that the available
sort
function expects to sort lines within a file, rather than fields within a line. To work around that, you could replace the field delimiters, line-by-line, with newlines prior to thesort
function, then replace the newlines with delimiters again in each line after sorting.There are a number of available text processing utilities which would allow you to do that (including
sed
,awk
, or even the simpletr
) however the bash shell itself can do a lot nowadays. Assuming you meant for the input to be comma-delimited (you have a mix of commas and whitespace delimiters in your example) you could do:If you do need to handle space delimiters in the input, then you can add them as part of a character list
[, ]
for the input substring replacement:(note that the output remains strictly comma-delimited though).
Here comes an
awk
solution,Explanation:
awk '{ n=split($1,a,","); asort(a); for(i=0;i<=n;i++) { print a[i];}}'
awk Splits the field 1 according to the delimiter
,
and store each value into the arraya
finally the top position is stored into the variablen
. Nextasort(a)
function sort down the array values.Then the for loop inside the awk command prints the sorted values in the format of record by record.xargs | sed -e 's/ /,/g'
xargs
combines all the rows into a single row.sed -e 's/ /,/g'
It replaces the spaces with commas
,
while read -r line;
All the above
awk
,xargs
,sed
functions are done line by line with the help ofwhile
loop.Using tr and sed
Similar in spirit to what jkt123 wrote:
It iterates over the lines, and for each line replaces commas by newlines, sorts the resulting lines numerically, then turns newlines back to commas. The main problem is that this will end the whole result with a comma not a newline, which is addressed by that last sed. It strips the last comma and also implicitely adds a newline to its output.
Using bash arrays
Here is a different approach to deal with this “join with commas” issue:
Or written with line wraps:
It uses a bash array to store the result of the sorted row, and makes use of the way bash expands arrays into string literals using the
IFS
special variable.python -c "your code here" input.txt
Or, if your program has multiple lines and
eval()
is too slow:python yourprogram.py input.txt
This oneliner works:
You can do this easily using perl
consider you have file
text.txt
Now the following perl code will sort the rows in
text.txt
After sorting
The
shortestsolution using a perl oneliner:I needed this functionality too, and a solution I found is as follows (assuming data are in test file):