Tengo muchos archivos de texto en un directorio y quiero eliminar la última línea de cada archivo en el directorio.
¿Cómo puedo hacerlo?
text-processing
files
ThehelfarisedPheonix
fuente
fuente

Respuestas:
Si tiene acceso a
vim, puede usar:fuente
Puedes usar este bonito oneliner si tienes GNU
sed.Eliminará la última línea de cada archivo no oculto en el directorio actual. Cambiar
-ipor GNUsedsignifica operar en su lugar y'$ d'ordenasedque elimine la última línea (lo que$significa último y lo quedsignifica eliminar).fuente
-ique es un GNUism, así que esto es discutible, pero perdería mi antigua posición de barba si no señalara que algunas versiones anteriores desedno te permiten poner ningún espacio en blanco entre el$y eld(o, en general, entre el patrón y el comando).*(.)a glob para los archivos normales, no sé acerca de otras conchas.Todas las otras respuestas tienen problemas si el directorio contiene algo diferente a un archivo normal, o un archivo con espacios / líneas nuevas en el nombre del archivo. Aquí hay algo que funciona independientemente:
find "$dir" -type f: Encontrar los archivos en el directorio$dir-type fque son archivos regulares;-execejecutar el comando en cada archivo encontradosed -i: Editar los archivos en su lugar;'$d': Eliminar (d) la última ($la línea).'+': le dice a find que continúe agregando argumentos ased(un poco más eficiente que ejecutar el comando para cada archivo por separado, gracias a @zwol).Si no desea descender en subdirectorios, a continuación, puede agregar el argumento
-maxdepth 1afind.fuente
findesto está escrito de manera más eficientefind $dir -type f -exec sed -i '$d' '{}' '+'.)-print0no está presente en el comando completo, ¿por qué ponerlo en la explicación?-depth 0no funciona (findutils 4.4.2), debería funcionar-maxdepth 1.-exec.Usar GNU
sed -i '$d'significa leer el archivo completo y hacer una copia sin la última línea, mientras que sería mucho más eficiente simplemente truncar el archivo en su lugar (al menos para archivos grandes).Con GNU
truncate, puedes hacer:Si los archivos son relativamente pequeños, eso probablemente sería menos eficiente, ya que ejecuta varios comandos por archivo.
Tenga en cuenta que para los archivos que contienen bytes adicionales después del último carácter de nueva línea (después de la última línea) o, en otras palabras, si tienen una última línea no delimitada , entonces, dependiendo de la
tailimplementación,tail -n 1devolverán solo esos bytes adicionales (como GNUtail), o la última línea (delimitada correctamente) y esos bytes adicionales.fuente
|wc -cen latailllamada? (o a${#length})${#length}no funcionaría ya que cuenta caracteres, no bytes, y$(...)eliminaría el carácter de nueva línea de cola, por${#...}lo que estaría desactivado por uno, incluso si todos los caracteres fueran de un solo byte.Un enfoque más portátil:
No creo que esto necesite ninguna explicación ... excepto tal vez que en este caso
des lo mismo$dya queedpor defecto selecciona la última línea.Esto no buscará recursivamente y no procesará archivos ocultos (también conocidos como archivos de puntos).
Si desea editarlos también, vea Cómo hacer coincidir * con archivos ocultos dentro de un directorio
fuente
[[]]a[], será totalmente compatible con POSIX. ([[ ... ]]es un Bashismo.)[[no es un bashism )One-liner compatible con POSIX para todos los archivos que comienzan recursivamente en el directorio actual, incluidos los archivos de puntos:
.txtSolo para archivos, de forma no recursiva:Ver también:
fuente