Usando awk
Comando
awk '{ if($0 ~ /PATTERN/) { if(!FIRST) FIRST=NR; LAST=NR } } END { print LAST-FIRST }' FILE
Como funciona
-
awk '{ COMMANDS } END { FINALCOMMAND }' FILEexecutaCOMMMANDSpara cada linha deFILE.Depois, executa
FINALCOMMAND. -
if($0 ~ /PATTERN/) { ... }verifica sePATTERNocorre na linha ($0).Se isso acontecer,
...será executado. -
The first time the pattern occurs,FIRST 'estará vazio.Portanto,
if(!FIRST) FIRST=NRarmazenará o número da linha (NR) emFIRST. -
Para cada ocorrência,
LAST=NRarmazenará o número da linha (NR) emLAST.Após processar todas as ocorrências,
LASTmanterá o número da linha da última ocorrência. -
print LAST-FIRSTimprime a diferença entre o número da última e da primeira linha.
Usando apenas grep , head e tail
Script
MATCHES=$(grep -n PATTERN FILE)
FIRST=$(echo "$MATCHES" | head -n 1 | grep -Po "^\d+"); [ $FIRST ] || FIRST=0
LAST=$(echo "$MATCHES" | tail -n 1 | grep -Po "^\d+"); [ $LAST ] || LAST=0
SPAN=$(($LAST - $FIRST))
Como funciona
-
grep -n PATTERN FILEmostra todas as linhas emFILEmatchingPATTERN, precedidas pelo número da linha delas. -
echo "$MATCHES" | head -n 1mostra a linha primeiro deMATCHESegrep -Po "^ *\d+"filtra tudo, exceto o número da linha.depois.
[ $FIRST ] || FIRST=0verifica seFIRSTfoi definido. Caso contrário, fica definido para0. -
echo "$MATCHES" | tail -n 1mostra a linha última deMATCHESegrep -Po "^ *\d+"filtra tudo, menos o número da linha.depois.
[ $LAST ] || LAST=0verifica seLASTfoi definido. Caso contrário, fica definido para0. -
$(($LAST - $FIRST))calcula a diferença entre o número da última e da primeira linha.