Eliminar primera línea de un archivo


110

¿Cómo puedo eliminar la primera línea de un archivo y guardar los cambios?

Intenté esto pero borra todo el contenido del archivo.

$sed 1d file.txt > file.txt

Respuestas:


81

La razón por la que file.txt está vacío después de ese comando es el orden en que el shell hace las cosas. Lo primero que sucede con esa línea es la redirección. El archivo "file.txt" se abre y trunca a 0 bytes. Después de eso, se ejecuta el comando sed, pero en ese momento el archivo ya está vacío.

Hay algunas opciones, la mayoría implica escribir en un archivo temporal.

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, puede usar sed -i .bak '1d' file.txt.

1
¿Hay alguna manera que no incluya el archivo temporal? De todos modos, esto hará el truco. ¡Muchas gracias!
kickass13

@ kickass13 posiblemente usando un editor de texto como ed.
jordanm

66
El edcomando sería: printf "%s\n" 1d w q | ed file.txt(I heart ed)
glenn jackman

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

141

Una opción alternativa muy liviana es simplemente 'ajustar' todo menos la primera línea (esta puede ser una forma fácil de eliminar encabezados de archivos en general):

# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout

Siguiendo a @Evan Teitelman, puedes:

tail -n +2 file.txt | sponge file.txt

Para evitar un archivo temporal. Otra opción podría ser:

echo "$(tail -n +2 file.txt)" > file.txt

Etcétera. Prueba de la última:

[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 ~]$ 

Vaya, perdimos una nueva línea (según el comentario de @ 1_CR a continuación), intente en su lugar:

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 ~]$ 

Volviendo a sed, intente:

printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt

o quizás

echo -e "$(sed '1d' file.txt)\n" > file.txt

Para evitar efectos secundarios.


Lo acabo de probar en mi sistema Fedora y la salida está arriba. Estás en lo correcto, gracias por señalarlo.
AsymLabs

El tailtruco funcionó para mí (tardó menos de 3 segundos en un archivo de 130 MB). ¡Gracias!
elo80ka

echo "$(tail -n +2 file.txt)" > file.txtEs la respuesta perfecta.
Alex Raj Kaliamoorthy

¡Gracias! echo "$ (tail -n +2 file.txt)"> file.txt funciona para mí como un encanto!
Arsenii

16

También echa un vistazo a spongepartir moreutils. spongeabsorbe los datos de la entrada estándar hasta que el final de escritura de la entrada estándar se cierra antes de escribir en un archivo. Se usa así:

sed '1d' file.txt | sponge file.txt

14

Este tema es de interés, por lo que pruebo el punto de referencia de 3 maneras:

  1. sed '1d' d.txt > tmp.txt
  2. tail -n +2 d.txt > tmp.txt
  3. sed -i '1d' d.txt

Tenga en cuenta que el objetivo d.txtes un archivo de 5.4GB

Obtén el 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

Conclusión: a continuación parece ser la forma más rápida:

sed '1d' file.txt > tmpfile; mv tmpfile file.txt


Su sed '1d' d.txtmétodo no incluyó (o eso parece al leer sus pruebas) el mvcomando. En mis pruebas en FreeBSD con un archivo de 20 MB, sed -ifue el más rápido.
Sopalajo de Arrierez

9

exse puede usar para una verdadera edición in situ que no involucra un archivo temporal

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

2
ex usa un archivo temporal. strace -e open ex -c ':1d' -c ':wq' foo. ex trunca el archivo original con el archivo temporal, mientras que la opción -i de GNU sed sobrescribe el original con el archivo temporal. No estoy seguro de cómo funciona el sed de BSD.
llua

@llua, tienes razón. También me di cuenta de eso, pero más tarde
iruvar el

3

La forma más corta y sencilla de eliminar la primera línea de un archivo usando sedes:

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

3

Puede usar Vim en modo Ex:

ex -s -c '1d|x' file.txt
  1. 1 encontrar la primera línea

  2. d Eliminar

  3. x guardar y cerrar


0

Este comando eliminará 1 línea y guardará como "file.txt".

sed '1d' file.txt  > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt

0

Para eliminar una línea de praticiler en el archivo

  1. Eliminar primera línea

Archivo Sed '1d'

  1. Eliminar primera y tercera línea

Archivo Sed '1d3d'

Eliminar personaje en línea

1 Eliminar los dos primeros charter en lin

Archivo de Sed /^..//

2 Eliminar las dos últimas líneas de chrectercina

Archivo de Sed / .. £ //

3 Eliminar línea en blanco

Archivo Sed '/ ^ £ / d'


44
¿Los británicos retomaron las colonias? La última vez que miré, £$.
G-Man

£ indicaba signo doller ..
Vivek parikh

0

Podría usar vim para hacer esto:

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

-2

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

// muestra contenido en el archivo 01 pero elimina la primera y tercera línea


2
el comando sed le das eliminará las líneas 1, 2 y 3.
icarus

1
Esto elimina más de lo solicitado y no "guarda los cambios"
Jeff Schaller
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.