Como remover linhas do arquivo de texto grande usando o bash

3

Eu tenho um arquivo de texto enorme (arquivo de log) no meu CentOS que eu gostaria de remover parte superior de, provavelmente, milhares de linhas por dia. (Ou provavelmente apenas dividido em dois)

Eu pesquisei este site e descobri que a maioria usa o grep, sed para remover as linhas mas a saída para outro arquivo. Não tenho certeza se é possível usar o shell script (bash) para atualizar o arquivo? em vez de:

sed current file > new file
cp new file > current file

Obrigado!

    
por forestclown 10.03.2012 / 03:02

5 respostas

5

sed --in-place $filter $file

    
por 10.03.2012 / 03:22
5

Não existe uma maneira simples de remover linhas desde o início do arquivo!

Mesmo usando sed -i , você cria um novo arquivo conforme mostrado com os seguintes comandos ( > é meu prompt):

> echo "Helo World" > toto
> ls -i toto
147543 toto
> sed -i -e 's/Helo/Hello/' toto
> ls -i toto
147292 toto

Observe que o número do inode não é o mesmo. Isso significa que você cria um novo arquivo com o mesmo nome, não que você modifique o arquivo no lugar.

Isso é importante se o arquivo de log for aberto por um programa enquanto você executa esta operação. Se for, você criará um novo arquivo enquanto o programa que mantém o arquivo continuará gravando no arquivo antigo. Para mostrar isso, vamos tentar o seguinte:

for f in $(seq 1 100); do date; echo $f; sleep 1; done > file1&
ln file1 file2
sleep 5
sed -i -e '1,10d' file1
ls -l file1 file2
sleep 5
ls -l file1 file2

O segundo ls mostrará o mesmo tamanho para file1 e um tamanho crescente para file2 . Se eu não tivesse feito um ln antes de executar sed , o arquivo original continuaria crescendo sem ser acessível pela hierarquia do sistema de arquivos. Isso resultaria em espaço de uso no disco, conforme mostrado por df , mas não mostrado por du . Mais informações podem ser encontradas aqui e aqui .

A rotação do log é seu amigo aqui, mas isso não pode ser feito sem a ajuda do programa de registro. Deveria haver uma maneira de dizer ao programa para fechar e reabrir o arquivo, então o novo arquivo seria usado, mas o log escrito após o início do sed e o fim da reabertura do arquivo poderiam ser perdidos Se você não deseja perder logs, copie o arquivo primeiro, peça ao programa para reabrir o arquivo e modifique o arquivo copiado. Isso é o que o logrotate permite que você faça com o mínimo de scripts.

Você pode ler mais sobre este assunto aqui (apache 1.3) , aqui (apache 2.4) e aqui (bind 9) .

    
por 11.03.2012 / 23:01
2

Você pode usar o Vim no modo Ex:

ex -sc '1d2000|x' file
  1. 1 passar para a primeira linha

  2. 2000 selecione 2000 linhas

  3. d delete

  4. x salvar e fechar

por 17.04.2016 / 00:06
0

I got a huge text file (log file) in my CentOS which I would like to remove top part of

você pode usar o tail para gerar um novo arquivo contendo apenas as últimas N linhas

tail -n logfile >newlogfile
zcat logfile > $(date +%Y%m%d)logfile.gz && mv -f newlogfile logfile 2>/dev/null

, probably couple of thousand lines each day. (Or probably just split into two)

Você pode obter o número de linhas no arquivo com:

NUMLINES=$(awk 'END{print NR}' logfile)
#do some integer math and split with head and tail

I have search this site and found that most using grep, sed to remove the lines but output to another file. Not sure if it is possible that using shell script (bash) that I can update the file in place? instead of:

sim, você pode usar sed para excluir as primeiras n linhas

#remove the first 10 lines
sed -i '1,10d' logfile
    
por 13.03.2012 / 04:04
0

Configurar um cron job para girar o log? Hmm?

link

    
por 28.03.2012 / 00:01

Tags