Aqui está uma única chamada de sed que escreve a linha revisada para stdout, enquanto ao mesmo tempo salva o texto removido na variável de shell var :
$ var=$(echo "This X is test Y. But X is not test Y." | sed -nr 'h;s/[^X]*X([^Y]*)Y.*//;p;x;s/X[^Y]*Y/REPLACE/;w /dev/stderr') 2>&1
This REPLACE. But X is not test Y.
O valor de var é:
$ echo "==$var=="
== is test ==
Explicação:
-
hEste comando copia o padrão atual para o espaço de espera.
-
s/[^X]*X([^Y]*)Y.*//;pIsso remove tudo do espaço padrão, exceto o texto entre os primeiros
XeY, incluindo os espaços. Isso é então impresso no stdout. Esta é a saída que é capturada pelo shell e atribuída avar. -
xIsso copia o espaço de espera de volta para o espaço de padrão. Quando isso é feito, o espaço padrão contém uma cópia da linha de entrada original.
-
s/X[^Y]*Y/REPLACE/; w /dev/stderrA substituição é feita e o resultado é gravado em
stderr. -
2>&1Após o shell ter capturado o stdout em
var, isso instrui o shell a copiar stderr (que tem a linha com REPLACE) para stdout.
Além da manipulação da variável var
A variável var inclui os espaços iniciais e finais. Se o shell subseqüentemente submetesse var à divisão de palavras, esses espaços seriam removidos. Para evitar isso, quando var for referenciado, faça isso entre aspas duplas, como no exemplo acima.