Estou tentando descobrir se é possível editar um arquivo em um único comando sed sem transmitir manualmente o conteúdo editado para um novo arquivo e renomear o novo arquivo para o nome do arquivo original. Eu tentei a -i
opção, mas meu sistema Solaris disse que -i
é uma opção ilegal. Existe uma maneira diferente?
300
-i
é uma opção no gnu sed, mas não está no sed padrão. No entanto, ele transmite o conteúdo para um novo arquivo e renomeia o arquivo para que não seja o que você deseja.Respostas:
A
-i
opção transmite o conteúdo editado para um novo arquivo e o renomeia nos bastidores.Exemplo:
e
no macOS .
fonte
sed -i "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>
Em um sistema em
sed
que não há a capacidade de editar arquivos, acho que a melhor solução seria usarperl
:Embora isso crie um arquivo temporário, ele substitui o original porque um sufixo / extensão vazio no local foi fornecido.
fonte
sudo
. Na minha opinião, a questão é sobre como evitar criar e renomear manualmente um arquivo temporário sem ter que instalar o GNU ou BSD mais recentesed
. Basta usar Perl.sed 's/foo/bar/g' file.txt > file.tmp && mv file.tmp file.txt
,. Só porque a edição no local renomeia usando um arquivo temporário, não significa que ele deve executar uma renomeação manual quando a opção não estiver disponível. Existem outras ferramentas por aí que podem fazer o que ele / ela quer, e Perl é a escolha óbvia. Como isso não é uma resposta para a pergunta original?sed
. A questão era realmente muito bom, mas é valor foi diminuído por pessoas que ou não podem ler as páginas man ou não pode ser incomodado para realmente perguntas lido aqui no SO.Observe que no OS X você pode obter erros estranhos como "código de comando inválido" ou outros erros estranhos ao executar este comando. Para corrigir este problema, tente
Isso ocorre porque na versão OSX de
sed
, a-i
opção espera umextension
argumento para que seu comando seja realmente analisado comoextension
argumento e o caminho do arquivo seja interpretado como o código de comando. Fonte: https://stackoverflow.com/a/19457213fonte
brew install gnu-sed
junto com umPATH
permitirá que você use a versão GNU do sed. Obrigado por mencionar; um arranhador de cabeça definitivo.O seguinte funciona bem no meu mac
Estamos substituindo foo por bar no arquivo de amostra. O backup do arquivo original será salvo no sample.bak
Para editar em linha sem backup, use o seguinte comando
fonte
Uma coisa a observar,
sed
não é possível gravar arquivos por si só, pois o único objetivo do sed é atuar como um editor no "fluxo" (ou seja, pipelines de stdin, stdout, stderr e outros>&n
buffers, soquetes e similares). Com isso em mente, você pode usar outro comandotee
para gravar a saída de volta no arquivo. Outra opção é criar um patch para canalizar o conteúdodiff
.Método Tee
Método de correção
ATUALIZAR:
Além disso, observe que o patch fará com que o arquivo mude da linha 1 da saída do diff:
O patch não precisa saber qual arquivo acessar, pois é encontrado na primeira linha da saída do diff:
fonte
/dev/stdin 2014-03-15
, respondeu 7 de janeiro - você é um viajante do tempo?/dev/stdin
não existe; portanto, você deve substituir/dev/stdin
por '-', um único hífen sem as aspas, para que os seguintes comandos funcionem:$ sed 's/oo/u/' fubar | diff -p fubar -
e$ sed 's/oo/u/' fubar | diff -p fubar - | patch
patch
isso também não será truncado. Eu acho que salvar a saída em outro arquivo e depoiscat
inseri-lo no original seria mais seguro.Não é possível fazer o que você quer
sed
. Mesmo versõessed
desse suporte à-i
opção de editar um arquivo no local fazem exatamente o que você declarou explicitamente que não deseja: elas gravam em um arquivo temporário e depois renomeiam o arquivo. Mas talvez você possa apenas usared
. Por exemplo, para alterar todas as ocorrências defoo
parabar
no arquivofile.txt
, você pode:A sintaxe é semelhante
sed
, mas certamente não é exatamente a mesma.Mas talvez você deva considerar por que não deseja usar um arquivo temporário renomeado. Mesmo se você não tiver
-i
suportesed
, poderá escrever facilmente um script para fazer o trabalho por você. Em vez desed -i 's/foo/bar/g' file
, você poderia fazerinline file sed 's/foo/bar/g'
. Esse script é trivial para escrever. Por exemplo:deve ser adequado para a maioria dos usos.
fonte
inline
e o chamaria como descrito acima:inline inputfile sed 's/foo/bar/g'
ed
apenas responda o que realmente funciona. Primeira vez que eu precisoed
. Obrigado. Uma pequena otimização é usarecho -e ",s/foo/bar/g\012 w"
ouecho $',s/foo/bar/g\012 w'
onde o shell permite evitartr
chamadas extras .ed
realmente não faz as modificações no local. A partir dastrace
saída, o GNUed
cria um arquivo temporário, grava as alterações no arquivo temporário e, em seguida, reescreve o arquivo original inteiro, preservando os links físicos. Natruss
saída, o Solaris 11ed
também usa um arquivo temporário, mas renomeia o arquivo temporário para o nome do arquivo original ao salvar com ow
comando, destruindo os links físicos.ed
que acompanha os macos atuais (Mojave, qualquer que seja o significado do jargão de marketing) ainda preserva os hardlinks. YMMVVocê poderia usar vi
fonte
O sed suporta edição no local. De
man sed
:Exemplo :
Digamos que você tenha um arquivo
hello.txt
com o texto:Se você deseja manter um backup do arquivo antigo, use:
Você terminará com dois arquivos:
hello.txt
com o conteúdo:e
hello.txt.bak
com o conteúdo antigo.Se você não deseja manter uma cópia, apenas não passe o parâmetro extension.
fonte
Você não especificou qual shell está usando, mas com o zsh você pode usar a
=( )
construção para conseguir isso. Algo ao longo das linhas de:=( )
é semelhante a,>( )
mas cria um arquivo temporário que é excluído automaticamente quandocp
finalizado.fonte
Deve preservar todos os hardlinks, pois a saída é direcionada para substituir o conteúdo do arquivo original e evita a necessidade de uma versão especial do sed.
fonte
Se você estiver substituindo a mesma quantidade de caracteres e depois de ler atentamente a edição "in-loco" dos arquivos ...
Você também pode usar o operador de redirecionamento
<>
para abrir o arquivo para ler e escrever:Veja ao vivo:
No Bash Reference Manual → 3.6.10 Abrindo descritores de arquivo para leitura e gravação :
fonte
Como Moneypenny disse em Skyfall: "Às vezes, os modos antigos são os melhores". Kincade disse algo semelhante mais tarde.
Edição feliz no local. Adicionado '\ nw \ n' para gravar o arquivo. Desculpas pelo atraso na resposta ao pedido.
fonte
|
. @MattMontag\n
. [range] s / <old> / <novo> / <flag> é a forma do comando substituto - um paradigma ainda visto em muitos outros editores de texto (ok, vim, um descendente direto de ed) De qualquer forma, ag
bandeira significa "global" e significa "Cada instância em cada linha que você vê". O intervalo3,5
analisa as linhas 3-5.,5
olha StartOfFile-5,3,
olha as linhas 3-EndOfFile e,
olha StartOfFile-EndOfFile. Um comando de substituição global em todas as linhas que substituem "false" por "true". Em seguida, o comando de gravação,,w
é inserido.Muito bons exemplos. Eu tive o desafio de editar vários arquivos e a opção -i parece ser a única solução razoável para usá-lo no comando find. Aqui o script para adicionar "version:" na frente da primeira linha de cada arquivo:
fonte