Créditos para @dgig e @Paulo que me ajudou com o feedback deles! Final perl
one-liner aqui:
perl -lne 'if(/FOO/../BAR/){s/.*?(FOO)/$1/ if!$i++;s/BAR\K.*//&&print&&exit;print}' file
Explicação:
if(/FOO/../BAR/){ # perform the following actions on each line, starting
# with a line that contains FOO, and up to and including
# a line that contains BAR
s/.*?(FOO)/$1/ if!$i++; # only on the first line that contains FOO,
# delete all characters before FOO
s/BAR\K.*//&&print&&exit;# if the line contains BAR, remove characters
# after BAR, print the line and stop processing
print # simply print the line contents
Resposta antiga:
Créditos para @Paulo para uma simples solução sed
. É tão simples e fácil de ler em awk
:
awk '/FOO/,/BAR/' file
Pode ser muito simples: retorna linhas inteiras e não exatamente "uma parte do texto que começa na primeira ocorrência de FOO e termina na primeira ocorrência de BAR". Eu acredito que isso signifique que FOO deveria ser a primeira palavra, e BAR a última. Fazer exatamente isso requer uma resposta mais complicada. Deixe-me tentar realizar isso em perl
.
Caso simples (retorna linhas inteiras):
perl -lne 'print if /FOO/../BAR/' file
Caso complexo (exatamente de FOO a BAR):
perl -lne 'if(/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if!$i++;$_=~s/BAR\K.*//;print}' file
Eu gosto dessa solução equivalente, que atribui uma variável ao operador de intervalo:
perl -lne 'if($a=/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if$a==1;$_=~s/BAR\K.*// if$a=~/E/;print}' file
Nota: Assume-se que há apenas uma parte do texto a ser extraído, ou seja, não devemos encontrar outro FOO após o primeiro parágrafo delimitado por FOO e BAR.
Caso contrário, o caso simples já não é mais tão simples em awk
:
awk '/FOO/,/BAR/ {print; if ($0~/BAR/) {exit} }' file
e em perl
:
perl -lne '(print&&/BAR/&&exit) if /FOO/../BAR/' file
E as soluções complexas e mais refinadas se tornam:
perl -lne 'if(/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if!$i++;$_=~s/BAR\K.*//&&print&&exit;print}' file
e:
perl -lne 'if($a=/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if$a==1;$_=~s/BAR\K.*//&&print&&exit if$a=~/E/;print}' file
Este exemplo mostra como um one-liner pode passar de excepcionalmente claro e auto-explicativo para o que parece ser uma sequência obscura de caracteres aleatórios, por ter adicionado um pouco mais de complexidade ao problema. Sempre que necessário, recomendo escrever um script autônomo, sustentável e legível, no qual os recursos extras possam ser facilmente adicionados e os casos de canto levados em consideração.