Esvaziar o conteúdo de um arquivo

220

Estou ciente de três métodos para excluir todas as entradas de um arquivo.

Eles são

  • >filename
  • touch filename
  • filename < /dev/null

Desses três, eu abusei >filenamemais, pois isso requer o menor número de pressionamentos de tecla.

No entanto, gostaria de saber qual é o mais eficiente dos três (se houver algum método mais eficiente) em relação a arquivos de log grandes e pequenos.

Além disso, como os três códigos operam e excluem o conteúdo?

debal
fonte
24
Que tal truncate -s 0 filename?
Martin Thoma
Muito semelhante à diferença entre gato e '>' para zerar um arquivo onde você encontrará mais informações.
Stéphane Chazelas
O primeiro só funcionará se chamado a partir da linha de comando bash, mas não vai funcionar se for executado em um arquivo .sh
Marco Marsala
8
o toque não exclui o conteúdo, mas altera o tempo de acesso ao arquivo. Ele cria um arquivo vazio se não houver nenhum.
Hbogert 28/09/16

Respostas:

293

Na verdade, o segundo formulário touch filenamenão exclui nada do arquivo - ele cria apenas um arquivo vazio se não existir, ou atualiza a data da última modificação de um arquivo existente.

E o terceiro filename < /dev/nulltenta executar o nome do arquivo /dev/nullcomo entrada.

cp /dev/null filename trabalho.

Quanto a eficiente, o mais eficiente seria truncate -s 0 filename; veja aqui: http://linux.die.net/man/1/truncate .

Caso contrário, cp /dev/null filenameou > filenameambos estão bem. Os dois abrem e fecham o arquivo, usando a configuração truncar ao abrir. cptambém abre /dev/null, o que o torna marginalmente mais lento.

Por outro lado, truncateprovavelmente seria mais lento do que > filenamequando executado a partir de um script, pois a execução do comando truncate exige que o sistema abra o executável, carregue-o e execute-o.

cinza
fonte
9
Então, por que você diz que truncateé o mais eficiente?
Stéphane Chazelas
7
A operação truncar usa a chamada do sistema ftruncate () ou truncate () que não se preocupa em abrir o arquivo. Também evita a chamada do sistema close () que cp e > filenamemétodos precisam chamar.
ash
3
Na verdade, ele (pelo menos o GNU) faz um open + ftruncate + close (além das muitas chamadas de sistema que faz para carregar e inicializar a si mesmo), como de qualquer maneira, teria que criar o arquivo se não existisse e truncate(2)não faz isso.
Stéphane Chazelas
Se usarmos touch filename, o inode permanecerá o mesmo (desde que haja um arquivo antes)?
pMan 30/08/13
1
@pMan sim, você pode experimentá-lo e verificar comls -i
terdon
43

Outra opção pode ser:

echo -n > filename

Na página do manual de echo:

-n Do not print the trailing newline character.

Arturo Herrero
fonte
Como posso definir o tamanho? Dizer se eu quero 30000 caracteres nulos?
Utilizador
3

Existe um comando interno ":", disponível em sh, csh, bash e outros talvez, que pode ser facilmente usado com o operador de saída de redirecionamento que >trunca um arquivo:

#!/usr/bin/env bash
:> filename

O que eu gosto nisso é que ele não precisa de nenhum comando externo como "eco" etc.

Uma grande vantagem de truncar arquivos em vez de excluí-los / recriá-los é que os aplicativos em execução que funcionam com esse arquivo (por exemplo, alguém cria um tail -f filenameou um software de monitoramento, ...) não precisam reabri-lo. Eles simplesmente podem continuar usando o filedescriptor e obter todos os novos dados.

Mirko Steiner
fonte
man bashdescreve o :shell embutido como sem efeito.
Haxiel
Sim, e você o redireciona >para dentro do arquivo, que cria o arquivo se ele não existir e, se existir, você o trunca para zero. Melhor dito: você usa o :para não fazer nada, e >para redirecionar nada para um arquivo e truncá-lo.
Mirko Steiner
1
Por que você faria isso? > fileé suficiente para truncar um arquivo. Você não precisa de nenhum comando, apenas o operador de redirecionamento.
terdon
1
Às vezes, > filenamenão vai funcionar. por exemplo, no zsh. mas : > filenamefunciona ainda.
CS Pei
Bash e sh parecem gostar, > myfilemas por exemplo, erros csh com: Comando nulo inválido.
Mirko Steiner