Devido a um erro no aplicativo ainda não diagnosticado, tenho várias centenas de servidores com um disco completo. Há um arquivo que foi preenchido com linhas duplicadas - não um arquivo de log, mas um arquivo de ambiente do usuário com definições de variáveis (portanto, não posso simplesmente excluir o arquivo).
Eu escrevi um sed
comando simples para verificar as linhas adicionadas erroneamente e excluí-las, e testei em uma cópia local do arquivo. Funcionou como pretendido.
No entanto, quando tentei no servidor com o disco completo, recebi aproximadamente o seguinte erro (é da memória, não copia e cola):
sed: couldn't flush /path/to/file/sed8923ABC: No space left on deviceServerHostname
Claro, eu sei que não resta espaço. É por isso que estou tentando excluir coisas! (O sed
comando que estou usando reduzirá um arquivo de mais de 4000 linhas para cerca de 90 linhas.)
Meu sed
comando é apenassed -i '/myregex/d' /path/to/file/filename
Existe uma maneira de aplicar este comando apesar do disco completo?
(Ele deve ser automatizado, pois preciso aplicá-lo a várias centenas de servidores como uma solução rápida.)
(Obviamente, o bug do aplicativo precisa ser diagnosticado, mas, enquanto isso, os servidores não estão funcionando corretamente ...)
Atualização: a situação que enfrentei foi resolvida excluindo outra coisa que descobri que poderia excluir, mas ainda assim gostaria de responder a essa pergunta, que seria útil no futuro e para outras pessoas.
/tmp
é um não-go; está no mesmo sistema de arquivos.
Antes de liberar espaço em disco, testei e descobri que era possível excluir as linhas vi
abrindo o arquivo e executando :g/myregex/d
e, em seguida, salve as alterações com êxito :wq
. Parece que deve ser possível automatizar isso, sem recorrer a um sistema de arquivos separado para armazenar um arquivo temporário .... (?)
sed -i
cria uma cópia temporária para operar. Eu suspeito que ed
seria melhor para isso, embora eu não esteja familiarizado o suficiente para proibir uma solução real #
ed
você correr: printf %s\\n g/myregex/d w q | ed -s infile
mas tenha em mente algumas implementações também utilizam arquivos temporários como sed
(você pode tentar busybox ed - afaik ele não cria um arquivo temporário)
echo
. use printf
. e sed
adicione alguns caracteres que você soltar na última linha para evitar perder espaços em branco à direita. Além disso, seu shell precisa ser capaz de lidar com o arquivo inteiro em uma única linha de comando. esse é o seu risco - teste primeiro. bash
é especialmente ruim nisso (eu acho que é para fazer w / stack space?) e pode ficar doente com você a qualquer momento. os dois sed
são recomendados pelo menos para usar o buffer de pipe do kernel entre eles, mas o método é bastante semelhante. sua subcomando de comando também truncará file
se o sed w / in é ou não bem-sucedido.
sed '/regex/!H;$!d;x' <file|{ read v && cat >file;}
e, se funcionar, leia o resto da minha resposta. '