Para seguir o linux principe "uma tarefa - uma ferramenta":
-
Imprime apenas o bloco necessário (como no exemplo
CAD
)sed '/^\s*[0-9].*CAD/!d;:a;N;/\n\s*[0-9]/! s/\n/\x0/;ta;P;D'
-
Classifique na ordem inversa
sort -rn
-
Pegue apenas os primeiros blocos perguntados (como no exemplo
4
)head -4
Por favor, note que a maioria dos comandos linux operam com linhas (não blocos ) então os que foram convertidos em linhas alterando a linha \n
ew para o símbolo nulo ( \x0
) e então convertido de volta por tr .
Então, toda a linha:
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 'awk '
/^[ 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
' '\n'
Eu gosto da resposta do G-Man para alterar R
ow S
eparator, mas isso não é muito adequado no caso. Mais simples de fazer isso de maneira comum
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 'awk '
/^[ 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
' '\n'