br inserir do arquivo.txt para vários arquivos

4

Eu tenho esse sed & encontrar comando

find /home/www/ -name footer.php -exec sed -i 's/<\/body>/testmoe\n<\/body>/'

O que eu preciso para substituir o testmoe com dados no arquivo.txt para que seja gona,

find /home/www/ -name footer.php -exec sed -i 's/<\/body>/file.txt\n<\/body>/'

qualquer sugestão para corrigir meu comando

    
por user47556 07.05.2011 / 10:13

3 respostas

11

Para melhorar um pouco a resposta do @Iain, acho que você pode fazer isso em apenas uma passagem assim:

#!/bin/sh
sed -i '/<\/body/ {
    r /path/to/file
    a </body>
    d
}' $1

Isso procura por </body> , insere o arquivo no buffer, anexa </body> ao buffer e, em seguida, exclui o original </body> , que, conforme Iain apontou corretamente, não pode ser movido.

    
por 08.05.2011 / 01:03
4

Com sed , você precisa fazer várias passagens, pois o comando /RE/r <filename> insere o conteúdo de <filename> na saída após o / RE /. A maneira mais fácil de fazer isso com sed é

  • Insira "marcador de texto" antes do / RE / in passar um
  • Insira o conteúdo do arquivo após o "marcador de texto" passar dois
  • Excluir o "marcador de texto" no passo três

Isso é mais facilmente alcançado com um script que você pode chamar de encontrar

#!/bin/bash

sed -i '/<\/body>/i xyzzy' $1
sed -i '/xyzzy/r /path/to/file.txt' $1
sed -i  '/xyzzy/d' $1

então

find /home/www -name footer.php -exec /path/to/script {} \;
    
por 07.05.2011 / 18:41
1

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:

  1. perl -n faz um loop por STDIN linha por linha; para cada linha -e chama o script entre aspas simples, em que:
  2. $temp = $_ armazena a linha em um buffer temporário
  3. if ( $_ =~ /<\/body>/ ) procura por uma linha contendo </body>
  4. 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
  5. 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.

    
por 07.05.2011 / 11:05

Tags