Gostaria de executar uma busca e substituição em um arquivo HTML através da linha de comando.
Meu comando é mais ou menos assim:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html
Quando eu executo isso e olho o arquivo depois, ele está vazio. Excluiu o conteúdo do meu arquivo.
Quando eu executo isso depois de restaurar o arquivo novamente:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
O stdout
é o conteúdo do arquivo e a localização e substituição foram executadas.
Por que isso está acontecendo?
shell
unix
sed
io-redirection
BBales
fonte
fonte
perl -pi -w -e 's/STRING_TO_REPLACE/REPLACE_WITH/g;' index.html
sed
comando para encontrar uma string e substituir a linha inteira: stackoverflow.com/questions/11245144/...Respostas:
Quando o shell vê
> index.html
na linha de comando, ele abre o arquivoindex.html
para gravação , limpando todo o conteúdo anterior.Para corrigir isso, você precisa passar a
-i
opção desed
fazer as alterações embutidas e criar um backup do arquivo original antes que ele faça as alterações no local:Sem o .bak, o comando falhará em algumas plataformas, como o Mac OSX.
fonte
truncates the file
vez deopens the file
provavelmente torna mais claro.sed -i '' 's/blah/xx/g'
.bak
depoissed -i
?Um padrão alternativo e útil é:
Isso tem o mesmo efeito, sem usar a
-i
opção, e adicionalmente significa que, se o script sed falhar por algum motivo, o arquivo de entrada não será derrotado. Além disso, se a edição for bem-sucedida, não haverá mais nenhum arquivo de backup. Esse tipo de idioma pode ser útil nos Makefiles.Muitos seds têm a
-i
opção, mas nem todos; o posix sed é aquele que não. Se você deseja portabilidade, é melhor evitar isso.fonte
... && mv index.html{.tmp,}
sh
(se bem me lembro) não tem essa{...}
expansão. Em um Makefile, você pode estar usando umsh
pouco do quebash
, por isso, se você deseja portabilidade (ou fixação), precisará evitar essa construção.Isso faz uma substituição global no local no arquivo index.html. A citação da sequência evita problemas com espaço em branco na consulta e substituição.
fonte
use a opção -i do sed, por exemplo
fonte
's/STRING_TO_REPLACE/REPLACE_WITH/g'
-i
realiza edição de arquivos no local , para que não faça sentido combiná-lo com a entrada stdin .Para alterar vários arquivos (e salvar um backup de cada um como * .bak):
irá pegar todos os arquivos no diretório e substituí-lo
|
porx
isso é chamado de “torta Perl” (fácil como uma torta)fonte
sed
como requisito, apenas o usou como a ferramenta já testada.Você deve tentar usar a opção
-i
de edição no local.fonte
Se você tiver um link a ser adicionado, tente isso. Pesquise o URL como acima (começando com https e terminando com.com aqui) e substitua-o por uma string de URL. Eu usei uma variável
$pub_url
aqui.s
aqui significa pesquisa eg
substituição global.Funciona !
fonte
Atenção: este é um método perigoso! Abusa dos buffers de E / S no Linux e, com opções específicas de buffer, ele consegue trabalhar em arquivos pequenos. É uma curiosidade interessante.Mas não o use para uma situação real!
Além da
-i
opção desed
você pode usar otee
utilitário .De
man
:Portanto, a solução seria:
- aqui o
tee
é repetido para garantir que o pipeline seja armazenado em buffer. Todos os comandos no pipeline são bloqueados até obterem alguma entrada para trabalhar. Cada comando no pipeline inicia quando os comandos upstream gravam 1 buffer de bytes (o tamanho é definido em algum lugar ) na entrada do comando. Então o último comandotee index.html
, que abre o arquivo para gravação e, portanto, o esvazia, é executado após a conclusão do pipeline upstream e da saída no buffer dentro do pipeline.Provavelmente, o seguinte não funcionará:
- ele executará os dois comandos do pipeline ao mesmo tempo sem nenhum bloqueio. (Sem bloquear o gasoduto deve passar a linha de bytes por linha em vez de tampão por tampão. O mesmo que quando você executar
cat | sed s/bar/GGG/
. Sem o bloqueio é mais interativo e geralmente pipelines de apenas 2 comandos executados sem buffer e bloqueando. Pipelines mais longos são tamponados.) Atee index.html
vontade abra o arquivo para escrever e ele será esvaziado. No entanto, se você ativar o buffer sempre, a segunda versão também funcionará.fonte
>
, mas o ponto é que é uma solução quebrada que provavelmente resultará em perda de dados).O problema com o comando
é aquele
file
é truncado pelo shell antes que o sed realmente o processe. Como resultado, você obtém um arquivo vazio.A maneira mais fácil de fazer isso é usar
-i
para editar no local, como outras respostas sugeridas. No entanto, isso nem sempre é o que você deseja.-i
criará um arquivo temporário que será usado para substituir o arquivo original. Isso é problemático se o seu arquivo original era um link (o link será substituído por um arquivo normal). Se você precisar preservar os links, poderá usar uma variável temporária para armazenar a saída do sed antes de gravá-la no arquivo, desta forma:Melhor ainda, use em
printf
vez deecho
desde queecho
provavelmente processará\\
como\
em algumas conchas (por exemplo, traço):fonte
sed 'code' file > file.tmp; cat file.tmp > file; rm file.tmp
E a
ed
resposta:Para reiterar o que o codaddict respondeu , o shell lida com o redirecionamento primeiro , eliminando o arquivo "input.html" e, em seguida, o shell chama o comando "sed" passando um arquivo agora vazio.
fonte
ed
versão" dassed
respostas? ele executa mais rápido?sed
s não implementam-i
para editar no local.ed
é onipresente e permite salvar suas edições no arquivo original. Além disso, é sempre bom ter muitas ferramentas no seu kit.Você pode usar o Vim no modo Ex:
%
selecione todas as linhasx
salvar e fecharfonte
Eu estava procurando a opção em que posso definir o intervalo de linhas e encontrei a resposta. Por exemplo, eu quero mudar host1 para host2 da linha 36-57.
Você também pode usar a opção gi para ignorar o caso dos caracteres.
fonte
Com todo o respeito pelas respostas corretas acima, é sempre uma boa idéia "executar" scripts como esse, para que você não corrompa seu arquivo e precise reiniciar do zero.
Basta fazer com que seu script espalhe a saída na linha de comando em vez de gravá-la no arquivo, por exemplo, assim:
OU
Dessa forma, você pode ver e verificar a saída do comando sem ter seu arquivo truncado.
fonte