unix - print - grep between two patterns




sed editar o arquivo no lugar (9)

Eu estou tentando descobrir se é possível editar um arquivo em um único comando sed sem manualmente o streaming de conteúdo editado em um novo arquivo e renomear o novo arquivo para o nome do arquivo original. Eu tentei a opção -i mas meu sistema Solaris disse que -i é uma opção ilegal. Existe um caminho diferente?


Se você estiver substituindo a mesma quantidade de caracteres e depois de ler cuidadosamente a edição “In-place” dos arquivos ...

Você também pode usar o operador de redirecionamento <> para abrir o arquivo para ler e gravar:

sed 's/foo/bar/g' file 1<> file

Veja ao vivo:

$ cat file
hello
i am here                           # see "here"
$ sed 's/here/away/' file 1<> file  # Run the `sed` command
$ cat file
hello
i am away                           # this line is changed now

From Bash Reference Manual → 3.6.10 Abrindo descritores de arquivo para leitura e escrita :

O operador de redirecionamento

[n]<>word

faz com que o arquivo cujo nome é a expansão da palavra seja aberto para leitura e gravação no descritor de arquivo n ou no descritor de arquivo 0, se n não for especificado. Se o arquivo não existir, ele será criado.


A opção -i transmite o conteúdo editado para um novo arquivo e, em seguida, o renomeia nos bastidores.

Exemplo:

sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' filename

e

sed -i '' 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' filename

no macOS .


Em um sistema em que o sed não tem a capacidade de editar arquivos, acho que a melhor solução seria usar o perl :

perl -pi -e 's/foo/bar/g' file.txt

Embora isso crie um arquivo temporário, ele substitui o original porque um sufixo / extensão vazio no local foi fornecido.


Exemplos muito bons. Eu tive o desafio de editar muitos arquivos e a opção -i parece ser a única solução razoável usando-a dentro do comando find. Aqui o script para adicionar "versão:" na frente da primeira linha de cada arquivo:

find . -name pkg.json -print -exec sed -i '.bak' '1 s/^/version /' {} \;

Note que no OS X você pode receber erros estranhos como "código de comando inválido" ou outros erros estranhos ao executar este comando. Para corrigir esse problema, tente

sed -i '' -e "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>

Isso ocorre porque na versão OSX do sed , a opção -i espera um argumento de extension portanto, seu comando é realmente analisado como o argumento de extension e o caminho do arquivo é interpretado como o código de comando. Fonte: https://.com/a/19457213


O seguinte funciona bem no meu mac

sed -i.bak 's/foo/bar/g' sample

Estamos substituindo foo por barra no arquivo de amostra. Backup do arquivo original será salvo em sample.bak

Para editar inline sem backup, use o seguinte comando

sed -i'' 's/foo/bar/g' sample

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:

cp =(sed ... file; sync) file

=( ) é semelhante a >( ) mas cria um arquivo temporário que é automaticamente excluído quando o cp termina.


Você poderia usar o vi

vi -c '%s/foo/bar/g' my.txt -c 'wq'

mv file.txt file.tmp && sed 's/foo/bar/g' < file.tmp > file.txt

Deve preservar todos os hardlinks, já que a saída é direcionada de volta para sobrescrever o conteúdo do arquivo original e evita qualquer necessidade de uma versão especial do sed.





solaris