Vaciar el contenido de un archivo de texto.

16

Tengo un archivo de texto en mi directorio de inicio que recibe datos regularmente a través de un trabajo cron. Debido a que el trabajo cron proporciona datos dinámicos, también me gustaría establecer un trabajo cron para vaciar el contenido del archivo (el archivo aún debe existir). No necesito ayuda con cron, solo el comando que puede ayudar a vaciar el archivo.

sosytee
fuente
55
Alternativa: tail -n +1000 file.txt > file.txtdebería eliminar 1000 líneas y mantener las líneas más nuevas en el archivo (nunca se sabe cuándo podría necesitar parte del registro reciente para rastrear algo).
Rinzwind
2
Esa es en realidad una mejor opción que borrar el archivo en horas programadas.
Bruno Pereira
1
@Rinzwind, eso no funcionará ya que el archivo se truncará antes de que tail intente leerlo. Debe redirigir a un nuevo archivo y luego reemplazar el original por el nuevo.
psusi
Verdadero @psusi :) debe haber una redirección adicional allí.
Rinzwind

Respuestas:

28

La forma más simple:

> filename

Esta es una forma menos obvia y probablemente menos legible en un script de shell por otros, pero es todo lo que necesita.

Debido a que en >realidad no es un comando (es bash incorporado) no puede usar:

sudo > filename

cuando no tienes permisos en ese archivo. Pero puedes usar:

sudo bash -c "> filename"
Radu Rădeanu
fuente
qué tipo de permisos deben modificarse porque dice permiso denegado, ya he hecho chmod 755 para el archivo, o debería hacerlo una nueva publicación (me refiero a la pregunta de permisos)
sosytee
@sosytee Vea mis nuevas ediciones.
Radu Rădeanu
1
@sosytee Por supuesto que puede, pero use sudo crontab -epara agregar el trabajo cron para root, no para usted. O cambiar el permiso de archivo a 766 (o 666), no 755: sudo chmod 766 filename. Más sobre: codex.wordpress.org/Changing_File_Permissions
Radu Rădeanu
1
truncate filenamees un poco más limpio y simple que redirigir la salida vacía al archivo y no tiene problemas con sudo.
psusi
1
@psusi de truncate -s 0 filenamehecho puede hacer el truco. Puedes agregarlo como respuesta.
Radu Rădeanu
19

Hay una herramienta creada para ese propósito:

truncate -s 0 filename

Esto borrará el contenido pero seguirá siendo el mismo archivo (el inodo permanece igual).

Esto es importante porque algunos programas tienen un identificador para el archivo "por inodo". Suponga que "vacía" un archivo utilizando el método ingenuo de eliminar y volver a crear el archivo. Algunos programas aún pueden mantener un control del archivo antiguo (con el contenido anterior) incluso si ya no es visible por los medios habituales como ls.

Algunos enlaces a más detalles al final de esta respuesta.


Otra forma, quizás más fácil de recordar:

echo -n > filename

Esto también mantiene el mismo inodo.

Tenga en cuenta que ambos truncatey echo -nno están definidos por POSIX .

Para uso de cumplimiento POSIX cat /dev/null:

cat /dev/null > filename

Otra forma, más oscura y probablemente no agnóstica de conchas:

> filename

Si el archivo para truncar necesita privilegios de root para escribir, las siguientes líneas no funcionarán como probablemente se esperaba:

sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename

Esto se debe a que el shell realiza la redirección incluso antes de que se ejecute sudo. Eso significa que el acceso de escritura al archivo se realiza utilizando los privilegios del usuario que ejecuta el shell, no los privilegios que sudo otorgará.

Una solución alternativa es diferir la redirección a un shell ejecutado usando privilegios de sudo como este:

sudo sh -c "echo -n > filename"

Usarlo truncateno necesita una solución alternativa porque el acceso de escritura no lo realiza el shell sino truncateque es ejecutado por sudo utilizando los privilegios de sudo.

sudo truncate -s 0 filename

Para obtener algunos detalles sangrientos sobre los programas que mantienen abierto el archivo, incluso si el archivo se ha eliminado, puede leer lo siguiente:

lesmana
fuente
dice que ha denegado el permiso, se han utilizado chmod 755 nombre del archivo, pero aún se les niega el permiso
sosytee
2
tal vez tienes noclobber habilitado en bash?
lesmana
La respuesta más completa hasta ahora
AbdelHady
4

Para automatizar esto, puede usar logrotate. Simplemente cree un archivo de configuración para el archivo que desea vaciar, agregue otras configuraciones y puede tenerlo vacío todos los días automáticamente según los criterios que elija todos los días, o cuando el archivo sea más grande que etc.

Eche un vistazo aquí sobre cómo configurar logrotate: http://linuxcommand.org/man_pages/logrotate8.html

piotrektt
fuente
1
Estoy a favor de esta opción yo mismo. Usamos "file> 10 Mb" -> "tar.gz it to backup" "empty file". Y las copias de seguridad se eliminan después de 900 días.
Rinzwind
3

echo "" > foo_filees una manera simple de hacerlo, reemplazará todo el contenido de foo_file con "" haciéndolo en este caso vacío.

También puede usar cat /dev/null > foo_file, que leerá el dispositivo nulo y sobrescribirá su archivo sin nada.

Bruno Pereira
fuente
dice que ha denegado el permiso, se han utilizado chmod 755 nombre del archivo, pero aún se les niega el permiso
sosytee
¿Puedes leer los permisos de archivo con tu usuario normal por favor?
Bruno Pereira
sí, puedo leer el contenido como usuario normal
sosytee