The history of transactions done on an entity within our systems look like below:   1 BYM1 TSTAB 09NOV 0035 CABSometext 01   2 BYM1 TSTAB 09NOV 0035 CABCan be done - question      3 BYM1 TSTAB 09NOV 0035 CABSometext 02Sometext 03   6 BYM3 TSTAA 09NOV 0400 CAASome 04 text 04   7 BYM3 TSTAA 10NOV 0455 CACSometext 06Sometext 06 line 2   8 BYM3 TSTAA 10NOV 0455 CACSometext 07   9 BYM2 TSTAC 10NOV 0619 CADSome 08 text 0008 ABCDSome 08 text 0008 BB00Some 08 text 0008 CC00Some 08 text 0008 DD00Some 08 text 0008 EE00  10 BYM2 TSTAC 10NOV 0627 CADSomething BBBBBSSDGFSDSF  11 BYM2 TSTAC 10NOV 0627 CADSomething else  12 BYM2 TSTAC 10NOV 0627 CADWhat text here  13 BYM4 TSTAC 10NOV 0711 CADTired figuring out  19 BYM3 TSTAA 11NOV 0438 CAESome 04 text 05 05 05  20 BYM3 TSTAA 11NOV 0441 CAFNot so confidential now  21 BYM3 TSTAA 11NOV 0441 CAFSome 00 text 0009 X1X2  43 BYM3 TSTAA 11NOV 0441 CADSome 0A text 0009 ABCD  44 BYM3 TSTAA 11NOV 0441 CADSome 1B text  45 BYM3 TSTAA 12NOV 1455 CACSomething 0AADDBB8782 BYM3 TSTAA 12NOV 1610 CADSomething 0AADDBB8830 BYM3 TSTAA 12NOV 1612 CAASomething 0AADDBB9999 BYM3 TSTAA 12NOV 1722 CAASomething 0AADDBBThe blocks of text start with the line which has a number in the first 4 characters. (The number is actually a running sequence number and every transaction is indexed with that). The category (of the transaction) of the block is defined by the last three characters in the line which has the number. I am looking for a awk, sed (, vi, grep) script to search for blocks of text belonging to a category, sort the resultant blocks in descending order of the index (numbers), display the number of blocks I have asked for.For example, if I want to search of 4 blocks of category CAD the output I would like to see is:8782 BYM3 TSTAA 12NOV 1622 CADSomething 0AADDBB  44 BYM3 TSTAA 11NOV 0441 CADSome 1B text  43 BYM3 TSTAA 11NOV 0441 CADSome 0A text 0009 ABCD  13 BYM4 TSTAC 10NOV 0711 CADTired figuring outHow can I acheive this. Any help would be greatly appreciated :-)
How to identify, sort descending and display the top 10 blocks of text, by category
text processing;sed;awk;grep;sort
To follow linux principe one task -- one tool:Prints just necessary block (as in example CAD)sed '/^\s*[0-9].*CAD/!d;:a;N;/\n\s*[0-9]/! s/\n/\x0/;ta;P;D'Sort it in reverse ordersort -rnTake just first asked blocks (as in example 4)head -4Please note, that most linux commands operate with lines (not blocks) so the ones was converted into lines by changing \new line to null-symbol(\x0) then converted back by tr.So, all line: sed '/^\s*[0-9].*CAD/!d;:a;N;/\n\s*[0-9]/! s/\n/\x0/;ta;P;D' test.txt |sort -rn |head -4 |tr '\0' '\n'I like the G-Man answer's idea to change RowSeparator but this is not much suitable in the case. More simple to do it in ordinary wayawk '/^[ 0-9]{4} /{                 #for start block string    if($NF==cat){              #if it is a needed block        idx=$1        BLOCK[idx]=$0          #put line onto array with asigned index    }    else        idx=0                  #otherways asign index to 0    next                       #end itteration, go to start with next line}idx{                           #pass inappropriate blocks (with 0-index)BLOCK[idx]=BLOCK[idx] \n $0  #add line to array element with index}END{                           #when finish all lines    for(i=0;i<num;i++){        #do num times        max=0                  #asing `max` variable to min value        for(idx in BLOCK){     #for each index in array            idx=idx+0          #convert string index into decimal            if(idx>max)                        max=idx        #find maximum index (field No.1 in block)        }        if(!max)                         exit               #exit script if array empty (no more blocks)        print BLOCK[max]       #print block with maximum index        delete BLOCK[max]      #remove array element for furure search     }}' cat=CAD num=4 test.txt