A questão só é interessante se os delimitadores não estiverem necessariamente na mesma linha. Isso pode ser feito de várias maneiras (mesmo com sed
), mas awk
é mais flexível:
#!/bin/sh
awk '
BEGIN { found = 0; }
/xxx/ {
if (!found) {
found = 1;
$0 = substr($0, index($0, "xxx") + 3);
}
}
/yyy/ {
if (found) {
found = 2;
$0 = substr($0, 0, index($0, "yyy") - 1);
}
}
{ if (found) {
print;
if (found == 2)
found = 0;
}
}
'
Isso é testado levemente para os casos em que no máximo uma substring está em uma linha, usando esses dados:
this is xxx yy
first
second yyy
xxx.x
yyy
xxx#yyy
e esta saída (o script é "foo", os dados são "foo.in"):
$ cat foo.in|./foo
yy
first
second
.x
#
A maneira como funciona, é que os dados de entrada estão em $0
, e o awk combina os padrões xxx
e yyy
em sequência, permitindo que mais de uma coisa mude $0
até chegar ao último passo, onde é impresso.
A propósito, este exemplo não funcionaria para
xxxxHelloyyyxxxWorldyyy
pois verifica apenas a primeira correspondência. O script Perl dará resultados diferentes, já que ele usa uma correspondência gulosa em vez do índice / substr que usei no exemplo do awk. Perl, claro, pode fazer o mesmo - com um script.
O awk (como o Perl) é de formato livre, então pode-se expressar o comando como algo parecido com
awk 'BEGIN{found=0;}/xxx/{if(!found){found=1;$0=substr($0,index($0, "xxx")+3);}}/yyy/{if(found){found=2;$0=substr($0,0,index($0,"yyy")-1);}}{ if(found){print;if(found==2)found=0;}}'
mas isso raramente é feito, exceto por exemplo. Da mesma forma, sed
scripts (orientados a linhas), podem ser combinados em uma única linha com algumas restrições. Novamente, scripts complexos em sed
raramente são tratados dessa maneira. Em vez disso, eles são tratados como programas reais (consulte exemplo ).
Leitura adicional: