Eu tenho dois arquivos; file1
contendo -
hello world
hello bangladesh
e file2
contendo -
Dhaka in Bangladesh
Dhaka is capital of Bangladesh
Eu quero atualizar file2
como -
hello world
hello bangladesh
Dhaka in Bangladesh
Dhaka is capital of Bangladesh
Isso é feito por -
cat file1 file2 >> file3
mv file3 file2
Mas não quero criar um novo arquivo. Eu acho que usá sed
-lo pode ser possível.
Claro que é possível.
(A menos que você também esteja preocupado com arquivos temporários sendo potencialmente criados "sob o capô", já que praticamente todos os editores de texto funcionam dessa maneira. Não digo que seja totalmente impossível evitar qualquer possibilidade de criação de arquivo temporário sob o capô, mas não está coberto nesta resposta.)
Este é um comando compatível com POSIX usando
ex
, o antecessor não visual especificado pelo POSIX paravi
.printf
é usado apenas aqui para alimentar um comando para o editor. O queprintf
as saídas são:x
é salvar e sair.r
é "ler o conteúdo do arquivo nomeado."0
especifica o número da linha após a qual o texto lido deve ser colocado.Não há muitas maneiras de modificar arquivos no local usando ferramentas padrão. Mesmo que pareçam fazer isso, eles podem estar usando arquivos temporários (ou seja, GNU
sed -i
).ex
por outro lado, fará o truque:ex
é um editor de linha evim
evoluiu a partir dele, então esses comandos podem parecer familiares.0r filename
faz o mesmo que:0r filename
emvim
: insere o arquivo especificado após o endereço fornecido (número da linha). O número da linha aqui é 0, que é uma espécie de linha virtual que representa a linha antes da linha 1. Assim, o arquivo será inserido antes de qualquer texto existente.Então nós temos
wq
que salva e sai.Se você notar o comentário abaixo sobre isso ser "muito frágil", leve-o com um grão de sal. Se você quiser usar isso em um script, certifique-se de fazer a validação de pré-condição adequada (existem arquivos, são legíveis/graváveis, etc.). Bons roteiristas estariam fazendo isso de qualquer maneira.
Atualização: adicionei
-n
para resolver as preocupações do OP sobre como evitar a criação de arquivos temporários. Assumindo que o seuex
é implementado como partevim
(como é o caso na maioria dos sistemas modernos), este sinalizador suprimirá a criação normal do arquivo de troca que ovim
faz.só funciona com arquivos pequenos.
Semelhante à resposta de Jasen, esta é uma base para um utilitário.
A esponja de código no pacote moreutils é projetada para permitir uma capacidade in-loco para quase qualquer programa, embora externamente. Essencialmente, ele absorve a entrada do STDIN e, em seguida, grava a saída coletada em um nome de arquivo, mas NÃO com redirecionamento.
Gostamos da ideia, então criamos um trabalho parecido que coleta dados na memória, ao contrário de um arquivo como a esponja real faz.
Aqui está um trecho de script de shell para ilustrar isso:
Produzindo:
O código perl principal é bastante curto (especialmente sem verificação de erros, cuja adição pode ser desejável):
Execute em um sistema como:
Muitas felicidades ... felicidades, drl