2

I have a list like this:

1,kg,cat
1000,g,dog
20,g,apple

And I want to sort it by weight. 1 kg and 1000 g would be the same, so I'd like to have my rows sorted by weight. My data set is larger and has different units, and I want to know how to sort it so that the code can recognize that 3000 g is larger than 1 kg and so on.

3
  • I edited your question to fix the format and removed the spaces you had in your example. I assumed you only added them for clarity. If those spaces are actually present in your text file, please edit and return them.
    – terdon
    Mar 29, 2015 at 1:21
  • Also, what units does your file actually have? How many different units does this need to deal with?
    – terdon
    Mar 29, 2015 at 1:35
  • just grams (g) and kilograms (kg)
    – XY g
    Mar 29, 2015 at 2:06

3 Answers 3

4

If your file is too large to hold in memory, you could do:

$ awk -F, -v OFS="," '$2=="kg"{$1=1000*$1}1;' file | sort -n | 
    awk -F, -v OFS="," '$2=="kg"{$1=$1/1000}1;'
1000,g,dog
1,kg,cat
20,g,apple
4

I prefer the variant of not changing the existing data , but adding the sort criteria as new column, and removing that auxiliary sorting field at the end of the pipe:

awk -F, 'BEGIN {u["kg"]=1000; u["g"]=1}; {print $1*u[$2], $0}' file |
    sort -n | cut -d" " -f2-
2

You might be better off converting the units in the file, sorting them and using the resulting stored file.

sed -r 's/^([0-9]+),kg/\1000,g/' $file | sort -n

sed doesn't understand math, so if you have non-intigers you'll have to use something else. The following does the fast parse with sed, but uses bc to do actual math if needed.

sed -r 's/^([0-9]+),kg/\1000,g/;s/^([0-9\.]+),kg/echo $(echo \1*1000 | bc),g/e'
1
  • This changes the units. You will print everything in grams.
    – terdon
    Mar 29, 2015 at 11:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .