Sort based on one column

Hi All ,

I am having an input file like this

Input file

7 sks/jsjssj/ddjd/hjdjd/hdhd/Q 10 0.5 13 
    dkdkd/djdjd/djdjd/djd/QB 01 0.5 
    ldld/dkd/jdf/fjfjf/fjf/Q 0.5 
10 sjs/jsdd/djdkd/dhd/Q 01 0.5 21 
     kdkd/djdd/djdd/jdd/djd/QB 01 0.5 
     dkdld/djdjd/djd/Q 01 0.5 
     djd/jdkd/djd/djd/Qb 01 0.5 
19 dd/jdddjd/djd/djd/d/Q 10 0.5 100
    djd/jhd/jhd/jd/jd/Qb 10 0.5 
     djd/djd/djd/djd/djd/dj 01 0.5 

I need to sort the file based on last column and this should be my output file

Output file

19 dd/jdddjd/djd/djd/d/Q 10 0.5 100
    djd/jhd/jhd/jd/jd/Qb 10 0.5 
     djd/djd/djd/djd/djd/dj 01 0.5 
  10 sjs/jsdd/djdkd/dhd/Q 01 0.5 21 
     kdkd/djdd/djdd/jdd/djd/QB 01 0.5 
     dkdld/djdjd/djd/Q 01 0.5 
     djd/jdkd/djd/djd/Qb 01 0.5
   7 sks/jsjssj/ddjd/hjdjd/hdhd/Q 10 0.5 13 
    dkdkd/djdjd/djdjd/djd/QB 01 0.5 
    ldld/dkd/jdf/fjfjf/fjf/Q 0.5 

From Largest to smallest 5th COlumn

When I tried to use this command
sort -u -k5 input , it is disturbing other columns as well
All the columns should be sorted based on the 5th column but its not happening .

Hi, try:

awk '/^[0-9]/{print x}1' file | 
awk '{$1=$1}1' RS= FS='\n' OFS=§ |
sort -rnk 5,5 |
tr § '\n'
  1. Split the records with a blank line, using a digit on the first position as the indicator of a new record
  2. Replace the line terminators of records with an obscure character (paragraph character was used here (§), but it could be any character as long as it is not used in the input file) and remove the empty line that was introduced in step 1
  3. Numeric reverse sort of the records on the 5th field
  4. Reassemble the records to their original state by replacing the obscure character by a newline
1 Like

Hi Scrutinizer ,

Thanks for the code , but could you tell me what is the operator which is being used ,for is it $ for OFS ?
Could you help me out in brief explanation ?

Thanks
Kshitij

Hi ksitij, I was in the process of adding an explanation, it has been added to my post...

Hello kshitij,

Could you please try following. Written and tested with GNU awk and GNU sort.

awk '
/^[0-9]+/{
  val=$NF
}
{
  print val "@" $0
}'  Input_file  | 
sort -t'@' -nrsk1,1  | 
awk '
{
  sub(/.*@/,"")
}
1'

Output will be as follows.

19 dd/jdddjd/djd/djd/d/Q 10 0.5 100
    djd/jhd/jhd/jd/jd/Qb 10 0.5
     djd/djd/djd/djd/djd/dj 01 0.5
10 sjs/jsdd/djdkd/dhd/Q 01 0.5 21
     kdkd/djdd/djdd/jdd/djd/QB 01 0.5
     dkdld/djdjd/djd/Q 01 0.5
     djd/jdkd/djd/djd/Qb 01 0.5
7 sks/jsjssj/ddjd/hjdjd/hdhd/Q 10 0.5 13
    dkdkd/djdjd/djdjd/djd/QB 01 0.5
    ldld/dkd/jdf/fjfjf/fjf/Q 0.5

Thanks,
R. Singh

1 Like

@Ravinder nice different approach, in case the sort utility understands stable sort.

Thank you S. So you mean sort command's stable utility is not supported by all O.S systems. Sorry I only run it on a online terminal which has a GNU sort, not sure about any other O.S systems,if any details you want me to add then feel free to let me know I will add it in my answer then, cheers.

Thanks,
R. Singh

@ravinder, yes POSIX sort does not have a -s option, see:
sort

but GNU sort and BSD sort do.

1 Like

Might also work:

tac file | awk -F" +" '{TMP = $0 DL TMP; DL = "|" } /^[^ ]/ {print TMP | "sort -nrk5,5" ; TMP = DL = ""}' | tr '|' '\n'
sed -n '1h;/^\s/{H;$!b};x;s/\n/\r/gp' file | sort -k5,5nr | tr '\r' '\n'