Eu sei que é um pouco como a velha piada do West Country ("Você sabe como chegar a Yeovil?" "Se eu quisesse chegar a Yeovil, eu não começaria por aqui, senhor."), mas eu gostaria não use sed.
Tente
perl -ne '$temp = $_ ; if ( $_ =~ /<\/body>/ ) { open FD2, "file.txt" ; while (<FD2>) { print $_ ; } } ; print $temp;' < foo > bar
perl one-liners pode ser um pouco, bem, enigmático, então aqui está uma análise do que está acontecendo. O script perl:
-
perl -n
faz um loop por STDIN linha por linha; para cada linha -e
chama o script entre aspas simples, em que:
-
$temp = $_
armazena a linha em um buffer temporário
-
if ( $_ =~ /<\/body>/ )
procura por uma linha contendo </body>
-
open FD2, "file.txt" ; while (<FD2>) { print $_ ; }
: quando </body>
foi encontrado, abre um descritor de arquivo para o arquivo.txt e em um subloop lê cada linha desse arquivo e o grava em STDOUT; a reutilização de $_
nesse loop é a razão pela qual tivemos que armazená-lo temporariamente na etapa 2
-
print $temp;
escreve a linha originalmente lida para STDOUT, independentemente de uma correspondência ter sido encontrada na etapa 3
O resultado prático é que cada linha de STDIN é escrita em STDOUT, mas se alguma linha contiver </body>
, todo o conteúdo de file.txt
será inserido antes que a linha seja escrita.
É isso que você queria? Em caso afirmativo, envolvê-lo em find
, redirecionando STDIN e STDOUT e renomeando STDOUT em STDIN após a execução, é deixado como um exercício para você. Você também deve observar que, se acontecer de você ter mais de uma ocorrência de </body>
em seu arquivo, você obterá o conteúdo de file.txt
intercalado sempre que ocorrer.