Risposte:
Il motivo file.txt è vuoto dopo quel comando è l'ordine in cui la shell fa le cose. La prima cosa che succede con quella linea è il reindirizzamento. Il file "file.txt" viene aperto e troncato a 0 byte. Successivamente viene eseguito il comando sed, ma al momento il file è già vuoto.
Ci sono alcune opzioni, la maggior parte prevede la scrittura su un file temporaneo.
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 sarebbe: printf "%s\n" 1d w q | ed file.txt
(I heart ed)
-exec sed -i '1d' {} \;
Un'opzione alternativa molto leggera è solo quella di "mettere in coda" tutto tranne la prima riga (questo può essere un modo semplice per rimuovere le intestazioni dei file in generale):
# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout
Seguendo @Evan Teitelman, puoi:
tail -n +2 file.txt | sponge file.txt
Per evitare un file temporaneo. Un'altra opzione potrebbe essere:
echo "$(tail -n +2 file.txt)" > file.txt
E così via. Test ultimo:
[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 ~]$
Oops abbiamo perso una nuova riga (per @ 1_CR commento di seguito), prova invece:
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 ~]$
Tornando a sed, prova:
printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt
o forse
echo -e "$(sed '1d' file.txt)\n" > file.txt
Per evitare effetti collaterali.
tail
trucco ha funzionato per me (ha impiegato meno di 3 secondi su un file da 130 MB). Grazie!
echo "$(tail -n +2 file.txt)" > file.txt
è la risposta perfetta.
Anche dare un'occhiata sponge
da
moreutils
. sponge
assorbe i dati dall'input standard fino alla chiusura della fine di scrittura dell'input standard prima di scrivere su un file. È usato così:
sed '1d' file.txt | sponge file.txt
Questo argomento è interessante, quindi testare il benchmark in 3 modi:
sed '1d' d.txt > tmp.txt
tail -n +2 d.txt > tmp.txt
sed -i '1d' d.txt
Si noti che la destinazione d.txt
è un file da 5,4 GB
Ottieni il risultato:
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
Conclusione: sembra di seguito il modo più rapido:
sed '1d' file.txt > tmpfile; mv tmpfile file.txt
sed '1d' d.txt
metodo non ha incluso (o almeno così sembra leggendo i tuoi test) il mv
comando. Nei miei test su FreeBSD con un file di 20 MB è sed -i
stato il più veloce.
ex
può essere utilizzato per una vera modifica sul posto che non coinvolge un file temporaneo
ex -c ':1d' -c ':wq' file.txt
strace -e open ex -c ':1d' -c ':wq' foo
. ex tronca il file originale con il file temporaneo, dove l'opzione -i di GNU sed sovrascrive l'originale con il file temporaneo. Non sono sicuro di come funzioni la sed di BSD.
Puoi usare Vim in modalità Ex:
ex -s -c '1d|x' file.txt
1
trova la prima riga
d
Elimina
x
salva e chiudi
Questo comando rimuoverà 1 riga e salverà come "file.txt".
sed '1d' file.txt > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt
Per eliminare una riga del praticiler nel file
File Sed '1d'
File Sed '1d3d'
Elimina carattere in linea
1 Cancella i primi due charter in lin
File di Sed / ^..// '
2 Elimina le ultime due righe di crectercina
File Sed 's / .. £ //'
3 Elimina riga vuota
File Sed '/ ^ £ / d'
£
≠ $
.
Potrebbe usare vim per fare questo:
vim -u NONE +'1d' +wq! /tmp/test.txt
cat file01 | sed -e '1,3d'
// mostra il contenuto in file01 ma rimuove la prima e la terza riga
sed
, puoi usaresed -i .bak '1d' file.txt
.