Eu tenho um requisito no meu projeto para substituir algum texto existente em um arquivo como foo
por outro texto como fooofoo
:
abc.txt
name
foo
foo1
Então eu tentei:
sed -i "s/foo/fooofoo/g" abc.txt
No entanto, recebo este erro:
sed: opção ilegal -
i
Encontrei no manual que tenho que usar:
sed -i\ "s/foo/fooofoo/g" abc.txt
No entanto, isso também não está funcionando.
Encontrei alternativas perl
e awk
também uma solução no Solaris sed
seria muito apreciada.
Estou usando esta versão do bash:
Lançamento do GNU bash, versão 3.2.57 (1) (sparc-sun-solaris2.10)
text-processing
sed
solaris
tpsaitwal
fonte
fonte
/usr/gnu/bin/sed
para obter o suporte -i.Respostas:
Use
ed
. Está disponível na maioria das plataformas e pode editar seus arquivos no local.Desde que
sed
é baseado naed
sintaxe para substituir padrões é semelhante:fonte
ed
vez deex
, apenas curioso? (Eu sei que ambos são compatíveis POSIX e eu ligada com as especificações;.))ex
? Para responder à sua pergunta: como nunca uso,ex
não estou familiarizado com isso. btw, eu vi setups, ondeed
estava presente, masex
não foi (mas não o contrário) ... o mais notável é o meu laptop :)ex
comandos. Todos osvi
comandos que você pode digitar que começam com dois pontos sãoex
comandos. É claro que existem algumas extensões específicas do Vim, mas apenas o conjunto principal de comandos é incrivelmente poderoso e flexível e é suficiente para edições com script.ex
e ainda nãoed
.Se você não pode instalar o GNU sed, use:
Isso usa o redirecionamento para enviar a saída do sed para um arquivo temporário. Se sed for concluído com êxito, isso substituirá
abc.txt
o arquivo temporário.Como pode ser visto no código fonte do GNU sed , é exatamente
sed -i
isso que faz. Então, isso é tão eficiente quantosed -i
.Se
abc.tmp
já existe uma chance , convém usarmktemp
um utilitário semelhante para gerar o nome exclusivo para o temporário.fonte
ed
, pois ele lê o arquivo inteiro na memória.Se você quer o equivalente
sed -i.bak
, é bem simples.Considere este script para o GNU sed:
Podemos simplesmente substituir a linha marcada por
Isso move o arquivo existente para um backup e grava um novo arquivo.
Se queremos o equivalente a
então é um pouco mais complexo. Podemos abrir o arquivo para leitura como entrada padrão e desvinculá-lo antes de direcionar a saída do sed para substituí-lo:
Fazemos isso em um sub-shell, para que nosso stdin original ainda esteja disponível depois disso. É possível alternar entradas e retornar sem um subshell, mas dessa maneira me parece mais claro.
Observe que temos o cuidado de copiar primeiro, em vez de criar um novo
foo
arquivo - isso é importante se o arquivo for conhecido por mais de um nome (por exemplo, possui links físicos) e você quiser ter certeza de que não os quebrará. .fonte
Primeiro, você deve saber que o
i\
comando a que se refere é para inserir uma linha de texto - não para salvar o texto editado de volta no arquivo. Não há nenhuma maneira POSIX-especificado de usarsed
para isso.O que você pode fazer é usar
ex
, o que é especificado pelo POSIX :O
x
comando é para "salvar e sair". Você também pode usar,wq
masx
é mais curto.O
%
sinal no início do comando substituto significa "Aplique este comando a todas as linhas do buffer". Você poderia usar1,$s/find/replace/g
também.Uma grande diferença entre
ex
esed
é quesed
é um editor de fluxo . Só opera sequencialmente, linha por linha.ex
é muito mais flexível que isso e, de fato, você pode editar diretamente os arquivos de textoex
. É o antecessor imediato devi
.fonte
Usando
sed
e nenhum arquivo temporário visível :Você pode evitar a criação de um "arquivo temporário" visível separado :
Explicação
Os sistemas tipo Unix não removem o conteúdo do arquivo do disco até que ele seja desvinculado no sistema de arquivos e não seja aberto em nenhum processo. Portanto, você pode
exec 3<
abrir o arquivo no shell para ler o descritor de arquivo 3,rm
o arquivo (que o desassocia do sistema de arquivos) e depois chamarsed
o descritor de arquivo 3 usado como entrada.Observe que isso é muito diferente disso:
A diferença é que, quando você faz isso em um comando, o shell apenas abre o mesmo arquivo para leitura e escrita, com a opção de truncar o arquivo - já que ainda é o mesmo arquivo, você perde o conteúdo. Mas se você o abre para leitura e, em seguida
rm
, abre o mesmo nome de caminho para escrever, na verdade você está criando um novo arquivo com o mesmo nome de caminho (mas em um novo local de inode e disco, pois o original ainda está aberto): o conteúdo ainda está disponível.Depois que terminar, você pode fechar o descritor de arquivo que você abriu anteriormente (é o que a
exec 3<&-
sintaxe especial faz), que libera o arquivo original para que o sistema operacional possa excluir (marcar como não utilizado) seu espaço em disco.Ressalvas
Há algumas coisas a ter em mente sobre esta solução:
Você obtém apenas uma "análise" do conteúdo - não há uma maneira portátil de um shell "procurar" de volta no descritor de arquivo - portanto, uma vez que um programa lê parte do conteúdo, outros programas verão apenas o restante do arquivo. E
sed
vai ler o arquivo inteiro.Há uma pequena chance de o seu arquivo original ser perdido se o seu shell / script / sed for morto antes de terminar.
fonte
perl -i
é outra boa opção. A questão solicitado especificamente uma solução compatível com Solaris'sed
, em contraste com soluções comperl
eawk
que eles já mencionado encontrar. Além disso, minha resposta foi principalmente destinada a adicionar algo que achei útil saber e que faltava em qualquer uma das outras respostas.