2

I get a stream of data from an API with which look like this:

redID  blueID  whiteID  
1      22       2  
44     15       41  
2      15       15  
31     2       14 

What I need to do, is to sort this by blueID and then whiteID and then send somewhere else. But I don't know in advance how many columns there will be. All I know for sure is that there will always be at least those 2 columns.
So the desired output would look like this:

redID  blueID  whiteID  
31     2       14  
2      15      15  
44     15      41  
1      22      2 

Is there a way, perhaps in awk, to sort this stream based on a column name?
The only answer that I'm looking for is in a form of:

inputStream | some operations | sortedInputStream

Any ideas?

  • 1
    Please edit your question and show us your desired output. Ideally, show us an example that actually can be sorted. All your lines are identical so this isn't very informative. – terdon Jan 12 '16 at 16:59
  • i updated my question. Thanks for pointing this out – human Jan 12 '16 at 22:06
  • Do you know in advance that blueID and whiteID will always be the second and third columns, respectively? – gardenhead Jan 12 '16 at 22:22
  • Unfortunately no, the number of columns and their position may change, the only thing that is certain is each column's name. – human Jan 12 '16 at 22:38
  • Do you care if the output is in the same column order as the input? (It seems like it would be easier to rearrange the columns and then sort by first and second columns...but maybe not.) – Wildcard Jan 12 '16 at 23:03
0

You could do something like:

 # get the header line from the file and split each header to a different line
 header=$(head -1 $file_name | tr ' ' '\n')
 # get the index/line number of the blueID
 blueID_index=$(echo "$header" | grep -n "blueID" | sed 's/:.*//')
 # same for whiteID
 whiteID_index=$(echo "$header" | grep -n "whiteID" | sed 's/:.*//')
 # now build the sort command with the indexes you just computed
 sort -k$blueID_index -k$whileID_index
0

Thanks to the ideas from comments and other sources I was finally able to write this code and answer my own question:

   inputStream | awk -F'\t' -v OFS="\t" '{
            if ( col1 == ""){
                for (i=1;i<=NF;i++){
                    if ($i == "BlueId"){
                        col1=i;
                    }
                    else if ($i == "WhiteId"){
                        col2=i;
                    }
                }
            print "-1" "\t" "-1" "\t" $0
            }
            else {
                print $col1 "\t" $col2 "\t" $0
            }
        }' | sort -k1,1n -k2,2n | cut -f3- | outputStream

It works like this: it takes stream data, finds desired columns' numbers and prints in front of every row both values needed to sort. Then it sorts 1th and 2nd column and deletes them. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.