Respostas:
O motivo file.txt está vazio após esse comando é a ordem na qual o shell faz as coisas. A primeira coisa que acontece com essa linha é o redirecionamento. O arquivo "file.txt" é aberto e truncado para 0 bytes. Depois disso, o comando sed é executado, mas no momento o arquivo já está vazio.
Existem algumas opções, a maioria envolve a gravação em um arquivo temporário.
sed '1d' file.txt > tmpfile; mv tmpfile file.txt # POSIX
sed -i '1d' file.txt # GNU sed only, creates a temporary file
perl -ip -e '$_ = undef if $. == 1' file.txt # also creates a temporary file
ed
.
ed
comando seria: printf "%s\n" 1d w q | ed file.txt
(I heart ed)
-exec sed -i '1d' {} \;
Uma opção alternativa muito leve é apenas para 'arrastar' tudo, exceto a primeira linha (essa pode ser uma maneira fácil de remover os cabeçalhos de arquivos em geral):
# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout
Seguindo @Evan Teitelman, você pode:
tail -n +2 file.txt | sponge file.txt
Para evitar um arquivo temporário. Outra opção pode ser:
echo "$(tail -n +2 file.txt)" > file.txt
E assim por diante. Testando o último:
[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5
[user@work ~]$ echo "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5
[user@work ~]$
Opa, perdemos uma nova linha (de acordo com o comentário @ 1_CR abaixo), tente:
printf "%s\n\n" "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5
[user@work ~]$ printf '%s\n\n' "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5
[user@work ~]$
Voltando ao sed, tente:
printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt
ou talvez
echo -e "$(sed '1d' file.txt)\n" > file.txt
Para evitar efeitos colaterais.
tail
truque funcionou para mim (levou menos de 3 segundos em um arquivo de 130mb). Obrigado!
echo "$(tail -n +2 file.txt)" > file.txt
é a resposta perfeita.
Também dê uma olhada sponge
a partir
moreutils
. sponge
absorve os dados da entrada padrão até o final da gravação da entrada padrão fechar antes de gravar em um arquivo. É usado assim:
sed '1d' file.txt | sponge file.txt
Este tópico é de interesse, então testei o benchmark de três maneiras:
sed '1d' d.txt > tmp.txt
tail -n +2 d.txt > tmp.txt
sed -i '1d' d.txt
Observe que o destino d.txt
é um arquivo de 5,4 GB
Obtenha o resultado:
run 1 : sed '1d' d.txt > r1.txt
14s
run 2 : tail -n +2 d.txt > r2.txt
20s
run 3 : sed -i '1d' d.txt
88s
Conclusão: Parece abaixo a maneira mais rápida:
sed '1d' file.txt > tmpfile; mv tmpfile file.txt
sed '1d' d.txt
método não incluiu (ou pelo que parece, lendo seus testes) o mv
comando. Nos meus testes no FreeBSD com um arquivo de 20 MB, sed -i
foi o mais rápido.
ex
pode ser usado para edição in-loco verdadeira que não envolve um arquivo temporário
ex -c ':1d' -c ':wq' file.txt
strace -e open ex -c ':1d' -c ':wq' foo
. ex trunca o arquivo original com o arquivo temporário, onde a opção -i do GNU sed sobrescreve o original com o arquivo temporário. Não tenho certeza de como funciona o sed do BSD.
Você pode usar o Vim no modo Ex:
ex -s -c '1d|x' file.txt
1
encontre a primeira linha
d
excluir
x
salvar e fechar
Este comando removerá 1 linha e salvará como "file.txt".
sed '1d' file.txt > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt
Para excluir uma linha praticiler no arquivo
Arquivo Sed '1d'
Arquivo '1d3d' sed
Excluir caractere em linha
1 Excluir as duas primeiras cartas em lin
Arquivo Sed 's /^..//'
2 Exclua as últimas duas linhas de chrectercin
Arquivo Sed / .. £ // '
3 Excluir linha em branco
Arquivo Sed '/ ^ £ / d'
£
≠ $
.
Pode usar o vim para fazer isso:
vim -u NONE +'1d' +wq! /tmp/test.txt
arquivo de gato01 | sed -e '1,3d'
// mostra o conteúdo no arquivo01, mas remove a primeira e a terceira linha
sed
, você pode usarsed -i .bak '1d' file.txt
.