Usando awk
Comando
awk '{ if($0 ~ /PATTERN/) { if(!FIRST) FIRST=NR; LAST=NR } } END { print LAST-FIRST }' FILE
Como funciona
-
awk '{ COMMANDS } END { FINALCOMMAND }' FILE
executaCOMMMANDS
para cada linha deFILE
.Depois, executa
FINALCOMMAND
. -
if($0 ~ /PATTERN/) { ... }
verifica sePATTERN
ocorre na linha ($0
).Se isso acontecer,
...
será executado. -
The first time the pattern occurs,
FIRST 'estará vazio.Portanto,
if(!FIRST) FIRST=NR
armazenará o número da linha (NR
) emFIRST
. -
Para cada ocorrência,
LAST=NR
armazenará o número da linha (NR
) emLAST
.Após processar todas as ocorrências,
LAST
manterá o número da linha da última ocorrência. -
print LAST-FIRST
imprime 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 FILE
mostra todas as linhas emFILE
matchingPATTERN
, precedidas pelo número da linha delas. -
echo "$MATCHES" | head -n 1
mostra a linha primeiro deMATCHES
egrep -Po "^ *\d+"
filtra tudo, exceto o número da linha.depois.
[ $FIRST ] || FIRST=0
verifica seFIRST
foi definido. Caso contrário, fica definido para0
. -
echo "$MATCHES" | tail -n 1
mostra a linha última deMATCHES
egrep -Po "^ *\d+"
filtra tudo, menos o número da linha.depois.
[ $LAST ] || LAST=0
verifica seLAST
foi definido. Caso contrário, fica definido para0
. -
$(($LAST - $FIRST))
calcula a diferença entre o número da última e da primeira linha.