Você sempre pode fazer:
tac < fileName | sed '/EndPattern/,$!d;/StartPattern/q' | tac
Se o seu sistema não tiver o GNU tac , você poderá usar tail -r .
Você também pode fazer como:
awk '
inside {
text = text $0 RS
if (/EndPattern/) inside=0
next
}
/StartPattern/ {
inside = 1
text = $0 RS
}
END {printf "%s", text}' < filename
Mas isso significa ler todo o arquivo.
Observe que pode haver resultados diferentes se houver outro StartPattern entre um StartPattern e o próximo EndPattern ou se o último StartPattern não tiver um final EndPattern ou se houver linhas correspondentes aos dois StartPattern e EndPattern .
awk '
/StartPattern/ {
inside = 1
text = ""
}
inside {text = text $0 RS}
/EndPattern/ {inside = 0}
END {printf "%s", text}' < filename
Faria isso se comportar mais como a abordagem tac+sed+tac (exceto pelo caso não divulgado StartPattern ).
Esse último parece ser o mais próximo dos seus requisitos editados. Para adicionar o aviso seria simplesmente:
awk '
/StartPattern/ {
inside = 1
text = ""
}
inside {text = text $0 RS}
/EndPattern/ {inside = 0}
END {
printf "%s", text
if (inside)
print "Warning: EOF reached without seeing the end pattern" > "/dev/stderr"
}' < filename
Para evitar a leitura do arquivo inteiro:
tac < filename | awk '
/StartPattern/ {
printf "%s", $0 RS text
if (!inside)
print "Warning: EOF reached without seeing the end pattern" > "/dev/stderr"
exit
}
/EndPattern/ {inside = 1; text = ""}
{text = $0 RS text}'
Nota de portabilidade: para /dev/stderr , você precisa de um sistema com um arquivo especial (cuidado com o Linux se o stderr estiver aberto em um arquivo pesquisável que gravará o texto no início do arquivo em vez da posição atual dentro do arquivo) ou uma implementação de awk que o emula como gawk , mawk ou busybox awk (os trabalhos em torno do problema do Linux mencionado acima).
Em outros sistemas, você pode substituir print ... > "/dev/stderr" por print ... | "cat>&2" .