Elimina la prima riga di un file


110

Come posso eliminare la prima riga di un file e conservare le modifiche?

Ho provato questo, ma cancella l'intero contenuto del file.

$sed 1d file.txt > file.txt

Risposte:


81

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

2
Con BSD sed, puoi usare sed -i .bak '1d' file.txt.

1
c'è un modo che non include il file temporaneo? Comunque, questo farà il trucco. Molte grazie!
kickass13

@ kickass13 probabilmente usando un editor di testo come ed.
jordanm,

6
Il edcomando sarebbe: printf "%s\n" 1d w q | ed file.txt(I heart ed)
Glenn Jackman,

1
@jonayreyes-exec sed -i '1d' {} \;
jordanm,

141

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.


L'ho appena provato sul mio sistema Fedora e l'output è sopra. Hai ragione - grazie per averlo sottolineato.
AsymLabs

Il tailtrucco ha funzionato per me (ha impiegato meno di 3 secondi su un file da 130 MB). Grazie!
elo80ka,

echo "$(tail -n +2 file.txt)" > file.txtè la risposta perfetta.
Alex Raj Kaliamoorthy,

Grazie! echo "$ (tail -n +2 file.txt)"> file.txt funziona per me proprio come un fascino!
Arsenii,

16

Anche dare un'occhiata spongeda moreutils. spongeassorbe 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

14

Questo argomento è interessante, quindi testare il benchmark in 3 modi:

  1. sed '1d' d.txt > tmp.txt
  2. tail -n +2 d.txt > tmp.txt
  3. 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


Il tuo sed '1d' d.txtmetodo non ha incluso (o almeno così sembra leggendo i tuoi test) il mvcomando. Nei miei test su FreeBSD con un file di 20 MB è sed -istato il più veloce.
Sopalajo de Arrierez,

9

expuò essere utilizzato per una vera modifica sul posto che non coinvolge un file temporaneo

ex -c ':1d' -c ':wq' file.txt

2
ex usa un file temporaneo. 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.
llua,

@llua, hai ragione. L'ho notato anche io, ma più tardi
iruvar il

3

Il modo più breve e semplice per eliminare la prima riga da un file utilizzando sedè:

$ sed -i -n -e '2,$p' file.txt

3

Puoi usare Vim in modalità Ex:

ex -s -c '1d|x' file.txt
  1. 1 trova la prima riga

  2. d Elimina

  3. x salva e chiudi


0

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

0

Per eliminare una riga del praticiler nel file

  1. Elimina la prima riga

File Sed '1d'

  1. Elimina prima e terza riga

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'


4
Gli inglesi ripresero le colonie? L'ultima volta che ho guardato, £$.
G-Man,

£ indicava un segno da
bambola

0

Potrebbe usare vim per fare questo:

vim -u NONE +'1d' +wq! /tmp/test.txt

-2

cat file01 | sed -e '1,3d'

// mostra il contenuto in file01 ma rimuove la prima e la terza riga


2
il comando sed che dai rimuoverà le righe 1, 2 e 3.
icarus

1
Questo elimina più di quanto richiesto e non "mantiene le modifiche"
Jeff Schaller
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.