How to sort java's .property file containg <key> = <value> by <value> column?

2

How can I sort this property file from java project by its value column? The value contains tabs or spaces before or after the value. Here is how this file looks like,

key1    = value1
key2 =         value2       
key3 =  value1   
key4   =        value3       
key5 =          value4  
key6 = value5               
key7   =        value2          
key8     =                value5          
key9  =    value6     
key10   = value5

Now I want this file to be sorted like below. And the spaces or tabs, before or after values should also be trimmed.

key1 = value1
key3 = value1
key2 = value2
key7 = value2
key4 = value3
key5 = value4
key6 = value5
key8 = value5
key10 = value5
key9 =  value6

In addition to this I also want to see only key-value pairs having duplicate key, i.e. all key-values should be displayed; except key4, key5 and key9 because they are unique.

Kashyap Kansara

Posted 2016-07-16T19:10:57.740

Reputation: 247

Answers

3

To see all the lines sorted by value:

$ sort -k3,3 propfile | sed -E 's/[[:space:]]*$//; s/[[:space:]]+/ /g'
key1 = value1
key3 = value1
key7 = value2
key2 = value2
key4 = value3
key5 = value4
key10 = value5
key6 = value5
key8 = value5
key9 = value6

To see the lines sorted by value with non-repeated values removed:

$ sort -k3,3 propfile | sed -E 's/[[:space:]]*$//; s/[[:space:]]+/ /g' | uniq -f2 -D
key1 = value1
key3 = value1
key7 = value2
key2 = value2
key10 = value5
key6 = value5
key8 = value5

How it works

  • sort -k3,3 propfile

    This sorts propfile on the third field.

  • sed -E 's/[[:space:]]*$//; s/[[:space:]]+/ /g'

    This removes all trailing whitespace and then replaces any remaining runs of whitespace with a single blank.

  • uniq -f2 -D

    Ignoring the first two fields, -f2, and prints only duplicated lines, -D.

John1024

Posted 2016-07-16T19:10:57.740

Reputation: 13 893

It doesn't keep the order of the keys for the same value. – choroba – 2016-07-16T19:43:08.790

@choroba Did you see some part of the question where the OP specified that as desired outcome? – John1024 – 2016-07-16T19:45:35.527

That's how I understood "sorted like below". – choroba – 2016-07-16T19:58:19.280

2

Perl solution:

perl -ne '
    s/\s+/ /g;
    s/\s+$//;
    ($v, $k) = split / = /, $_, 2;
    push @{ $h{$k} }, $v;
    }{
    1 == @{ $h{$_} } and delete $h{$_} for keys %h;
    print map {
        $k = $_;
        map "$_ = $k\n", @{ $h{$k} }
    } sort keys %h' < input-file

The first two substitutions normalize the whitespace. Then, keys are hashed by values (imagine Hash<Value,Array<Key>>). Once the whole file is processed, the values with only one key are deleted, and the rest is printed, changing each element of the hash to a list of strings of the correct form.

choroba

Posted 2016-07-16T19:10:57.740

Reputation: 14 741

chroroba....your solution is also absolutely correct and output is exactly as expected. But I wanted solution using bash or commands and I am also not familiar with Perl, so I have upvoted your answer and chosen other answer as Best Answer. If I could chose more than one best answer I would definitely chose you answer as Best Answer also. – Kashyap Kansara – 2016-07-16T20:14:05.750