Acciones de FIND

¿Algo falla o no sabes como funciona? Pide ayuda aquí!
Responder
Avatar de Usuario
MuadDib69
Pi Master
Pi Master
Mensajes: 276
Registrado: 16 Dic 2019, 18:22
Agradecido: 60 veces
Agradecimiento recibido: 13 veces

Hola de nuevo, pingüino's lovers... :guiño2
He visto que FIND tiene una acción -printf (entre otras) que parece ser que "imprime" un archivo con los resultados del FIND (o eso entiendo, puedo estar equivocado porque toco de oído...).
Intento que cada vez que se ejecuta un find /media/discousb/Descargas/ -maxdepth 5 -type f -name "*.zipx" -delete con éxito (==encuentra y borra un *.zipx) se añada una línea a un fichero de texto con el nombre del archivo eliminado.
Encuentro esto

Código: Seleccionar todo

find . -type f -printf '%p\t%k KB\n'
"prints the filename (%p), a tab (\t), the size in kilobytes (%k), the suffix " KB", and then a newline (\n)"
aquí https://stackoverflow.com/questions/646 ... -file-name
pero, ¿no habrá que decirle donde se "imprime" el fichero y cómo se va a llamar?
y, ¿hay alguna manera de que la siguiente vez que borre algo haga un "append" (inventada de nombre) al mismo fichero para que se comporte como un log?
...sigo investigando...
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

Buenooooo :-)
Vamos por partes:

1. printf (print formatted) es una función que, en este caso, escribe en pantalla y permite añadir texto, variables, etc.
Es como un "echo" pero con potencia.
https://www.it.uc3m.es/pbasanta/asng/co ... tf_es.html
El parámetro printf formatea una cadena de texto y la envía a stdout, pero lo que hagas con la salida de ese comando es problema de otro, no de printf

2. Para comandos más complejos tienes el parámetro exec

Código: Seleccionar todo

~/upload $ find . -type f -exec echo "Nombre del archivo: " {} \; -exec echo "Borrando archivo " {} \;
Nombre del archivo:  ./111.txt
Borrando archivo  ./111.txt
Nombre del archivo:  ./222.txt
Borrando archivo  ./222.txt
Mira los muchos, muchos ejemplos de -exec en este link:
https://www.servidoresadmin.com/comando ... ll-script/

3. Al final, por comodidad y limpieza, acabarás creando un scipt en bash para gestionarlo mejor que con un sólo comando.
Y entonces vendrán los loops, las estructuras de control más sencillas:

Código: Seleccionar todo

for i in {1,2,3};
do 
  echo $i; 
done

1
2
3
¿Ves? creo un buclie y a la variable "i" le asigno números en este caso.
Y luego imprimo el valor de i usando $i

En mi ejemplo uso una enumeración {1,2,3}, pero podemos usar la salida de un comando.
Por ejemplo, podemos hacer un bucle con los datos que devuelve el comando ls:

Código: Seleccionar todo

for file in $(ls); 
do 
  echo $file; 
done

111.txt
222.txt
¿Ves? aquí la variable "file", en cada iteración, tiene el valor de cada una de las líneas que me devuelve el comando ls
Y esto me permite manipular la cadena de texto $file, puedo imprimirla en pantalla, copiarla, moverla...
Y sobre todo, puedo hacer varias funciones, una en cada línea:

Código: Seleccionar todo

for file in $(ls); 
do 
  echo Voy a borrar el archivo $file; 
  echo $file >> ./borrados.txt
  rm -f $file
done

Voy a borrar el archivo 111.txt
Voy a borrar el archivo 222.txt

$ cat borrados.txt 
111.txt
222.txt
Y en el próximo post, más :-)
Estos usuarios agradecieron al autor egrueda por el mensaje:
MuadDib69
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

Hasta ahora estábamos usando el comando "ls" para hacer un bucle de tipo "for"
También hemos visto cómo pasar una enumeración {1,2,3}

Otros ejemplo sencillo, usando un dierctorio (sin subdirectorios)

Código: Seleccionar todo

for file in ~/upload/*; do echo $file; done
Pero vamos a lo divertido, ahora que sabemos usar el for y tenemos el comando find, ¡vamos a juntarlos!

Código: Seleccionar todo

$ for file in $(find . -type f); do echo "Encontrado $file"; done
Encontrado ./111.txt
Encontrado ./222.txt
Encontrado ./borrados.txt
En este caso la variable "file" recoje cada una de las líneas que devuelve el comando "find . -type f"
Así puedo hacer cosas más complejas, como:

Código: Seleccionar todo

$ for file in $(find . -type f); 
do 
  echo "Encontrado $file"; 
  echo "Borrando $file" >> /ruta/hacia/borrados.txt
  rm -f $file
done
¿Se entiende ese ejemplo? :-)
Estos usuarios agradecieron al autor egrueda por el mensaje:
MuadDib69
Avatar de Usuario
MuadDib69
Pi Master
Pi Master
Mensajes: 276
Registrado: 16 Dic 2019, 18:22
Agradecido: 60 veces
Agradecimiento recibido: 13 veces

BUENOOOOOOOOOOOOOOOOOOOOOOOOOOOOO :duda :duda :duda
Me meto en un berenjenal y tú me llevas a un huerto industrial de berenjenas... pero en fin, gracias por tu tiempo.
Entiendo que algo así (abajo);
1-encuentra coincidencia de tipo de archivo *.zipx
2-lo guarda en el archivo de texto
3-lo borra
4-rinse&repeat por cada coincidencia

Código: Seleccionar todo

$ for file in $(find /media/discousb/Descargas/ -maxdepth 5 -type f -name "*.zipx"); 
do 
  echo "Encontrado $file"; 
  echo "Borrando $file" >> /media/discousb/Descargas/borrados.txt
  rm -f $file
done
Si no me he inventado nada de lo anterior (improbable), si hay 2 coincidencias (2 archivos .zipx), ¿añade el nombre del segundo archivo a borrados.txt o lo sobreescribe perdiendo la info del anterior?

Y gracias de nuevo, maestro jedai :mrgreen:
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

MuadDib69 escribió: 30 Oct 2024, 17:59 Si no me he inventado nada de lo anterior (improbable), si hay 2 coincidencias (2 archivos .zipx), ¿añade el nombre del segundo archivo a borrados.txt o lo sobreescribe perdiendo la info del anterior?
Aquí hemos usado este código:

Código: Seleccionar todo

echo "Borrando $file" >> /media/discousb/Descargas/borrados.txt
¿Ves el doble ">>"? Si pongo uno, sobrescribo el archivo. Si pongo 2, añado al final del archivo :-)

P.D. Y otro día te hablo de los bucles while xD
Estos usuarios agradecieron al autor egrueda por el mensaje:
MuadDib69
Avatar de Usuario
MuadDib69
Pi Master
Pi Master
Mensajes: 276
Registrado: 16 Dic 2019, 18:22
Agradecido: 60 veces
Agradecimiento recibido: 13 veces

probando en cero coma
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

MuadDib69 escribió: 30 Oct 2024, 18:06 probando en cero coma
Recuerda que puedes omitir la línea con el "rm" para estar seguro de a qué archivos afecta el script :-D
Estos usuarios agradecieron al autor egrueda por el mensaje:
MuadDib69
Avatar de Usuario
MuadDib69
Pi Master
Pi Master
Mensajes: 276
Registrado: 16 Dic 2019, 18:22
Agradecido: 60 veces
Agradecimiento recibido: 13 veces

ok, para primero ver lo que localiza, comprendido.
Y luego pensaba sustituirla por

Código: Seleccionar todo

  rm -f /media/discousb/Descargas/$file
para minimizar posibles daños :idea

o en vez de rm acudir de nuevo a find+delete

Código: Seleccionar todo

find /media/discousb/Descargas/ -maxdepth 5 -type f -name "*.zipx" -delete
¿qué te parece?
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

MuadDib69 escribió: 30 Oct 2024, 18:15 ok, para primero ver lo que localiza, comprendido.
Para probar sin borrar (dry run), puedes simplemente añadir un echo para ver el comando completo que ejecutará:
echo rm -f $file
MuadDib69 escribió: 30 Oct 2024, 18:15 Y luego pensaba sustituirla por

Código: Seleccionar todo

  rm -f /media/discousb/Descargas/$file
Ojo, si haces "find /media/discousb/Descargas/" el comando te devolverá las rutas completas, por ejemplo:
/media/discousb/Descargas/file.zipx

Si luego tú haces "rm -f /media/discousb/Descargas/$file" y la variable $file se sustituye por la ruta completa, entonces tendrás:
rm -f /media/discousb/Descargas//media/discousb/Descargas/file.zipx
MuadDib69 escribió: 30 Oct 2024, 18:15 o en vez de rm acudir de nuevo a find+delete

Código: Seleccionar todo

find /media/discousb/Descargas/ -maxdepth 5 -type f -name "*.zipx" -delete
Si metes el "-delete" el comando find no te devolverá ningun valor, por tanto no podrás guardarlo en el log
Estos usuarios agradecieron al autor egrueda por el mensaje:
MuadDib69
Avatar de Usuario
MuadDib69
Pi Master
Pi Master
Mensajes: 276
Registrado: 16 Dic 2019, 18:22
Agradecido: 60 veces
Agradecimiento recibido: 13 veces

prueba 1:
coloco sendos ficheros zipx en
../Descargas
../Descargas/temp
../Descargas/temp/uno

ejecuto manualmente script (creado con nano desde la rasp para evitar cosas raras del win) desde consola (permisos comprobados)

Código: Seleccionar todo

$ for file in $(find /media/discousb/Descargas/ -maxdepth 5 -type f -name "*.zipx");
do
  echo "Encontrado $file";
  echo "Borrando $file" >> /media/discousb/Descargas/borrados.txt
done
y devuelve...

Código: Seleccionar todo

$ ./borrazipx.sh
./borrazipx.sh: línea 1: $: orden no encontrada
./borrazipx.sh: línea 2: error sintáctico cerca del elemento inesperado `do'
./borrazipx.sh: línea 2: `do'
Pensando que era porque sobraba o faltaba un ; al final de alguna línea he hecho experimentos con gaseosa, pero con el mismo resultado.
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

jaja, sobra el símbolo $ que en algún momento habré copiado yo xD
Estos usuarios agradecieron al autor egrueda por el mensaje:
MuadDib69
Avatar de Usuario
MuadDib69
Pi Master
Pi Master
Mensajes: 276
Registrado: 16 Dic 2019, 18:22
Agradecido: 60 veces
Agradecimiento recibido: 13 veces

gou gou...

Código: Seleccionar todo

$ ./borrazipx.sh
Encontrado /media/discousb/Descargas/temp/2.zipx
Encontrado /media/discousb/Descargas/temp/uno/3.zipx
Encontrado /media/discousb/Descargas/1.zipx
Éxito total con la detección

Segunda prueba antes de borrarlos==guardar nombres en fichero texto --> (1) no muestra en pantalla "Encontrado..." (2) no crea el fichero borrados.txt

Código: Seleccionar todo

for file in $(find /media/discousb/Descargas/ -maxdepth 5 -type f -name "*.zipx");
do
  echo "Encontrado $file"
  echo "Borrando $file" >> /media/discousb/Descargas/borrados.txt
done

Tercera prueba; creo un fichero vacío "borrados.txt" antes de ejecutar el script en la carpeta indicada --> (1) los muestra en pantalla (2) los guarda en el txt
:mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen:

Cuarta, el dry run ese, añado el

Código: Seleccionar todo

echo rm -f $file

Código: Seleccionar todo

$ ./borrazipx.sh
Encontrado /media/discousb/Descargas/temp/1.zipx
rm -f /media/discousb/Descargas/temp/1.zipx
Encontrado /media/discousb/Descargas/temp/uno/1.zipx
rm -f /media/discousb/Descargas/temp/uno/1.zipx
Encontrado /media/discousb/Descargas/1.zipx
rm -f /media/discousb/Descargas/1.zipx
Éxito total.

DUDA: ¿el ";" es para finalizar cualquier línea salvo lo que va dentro de un "do"?
Avatar de Usuario
MuadDib69
Pi Master
Pi Master
Mensajes: 276
Registrado: 16 Dic 2019, 18:22
Agradecido: 60 veces
Agradecimiento recibido: 13 veces

Para darle la puntilla:
¿añadir timestamp a cada línea de archivo borrado? (en el .txt)
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

MuadDib69 escribió: 30 Oct 2024, 18:43 DUDA: ¿el ";" es para finalizar cualquier línea salvo lo que va dentro de un "do"?
Nah, es una manía mía jajaja.
Yo uso mucho el for en línea de comandos, todo seguido y sin salto de línea, entonces necesito punto y coma para separar las partes.
Lo correcto es acabar cada línea con ; excepto la línea "do" y "done":

Código: Seleccionar todo

for f in * ;
do
  echo "Hola $f";
done
Pero bash es bastante flexible y te admite también sin ;

Código: Seleccionar todo

for f in *
do
  echo "Hola $f"
done
La primera sintaxis es la correcta
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

MuadDib69 escribió: 30 Oct 2024, 18:44 Para darle la puntilla:
¿añadir timestamp a cada línea de archivo borrado? (en el .txt)
¡Me alegro de que me lo preguntes! Estaba pensando en ello mientras escribía una respuesta anterior pero no quería complicarte la vida xD
Podemos crear en nuestro script una variable con la fecha y hora actual, usando el comando date

Código: Seleccionar todo

date +'%Y-%m-%d %H:%I'
Lo puedo almacenar en una variable:

Código: Seleccionar todo

ahora=$(date +'%Y-%m-%d %H:%I')
echo $ahora
Y puedo usar la variable $ahora donde quiera, por ejemplo:

Código: Seleccionar todo

echo "[$ahora] Borrando $file" >> /media/discousb/Descargas/borrados.txt
Avatar de Usuario
MuadDib69
Pi Master
Pi Master
Mensajes: 276
Registrado: 16 Dic 2019, 18:22
Agradecido: 60 veces
Agradecimiento recibido: 13 veces

bruuuuutal :)
Es más divertido esto que muchos juegos online :ponpon
Como supongo que has de definir la variable antes del bucle, lo he puesto lo primero.
Resultado (cambiando orden fecha)

Código: Seleccionar todo

[30-10-2024 20:08] Borrando /media/discousb/Descargas/temp/2.zipx
[30-10-2024 20:08] Borrando /media/discousb/Descargas/temp/uno/3.zipx
[30-10-2024 20:08] Borrando /media/discousb/Descargas/1.zipx

La traca final:

Código: Seleccionar todo

ahora=$(date +'%d-%m-%Y %H:%I')
for file in $(find /media/discousb/Descargas/ -maxdepth 5 -type f -name "*.zipx");
do
  echo "Encontrado $file"
  echo "[$ahora] Borrado $file" >> /media/discousb/Descargas/borrados.txt
  rm -f $file
done

Código: Seleccionar todo

[30-10-2024 20:08] Borrado /media/discousb/Descargas/temp/2.zipx
[30-10-2024 20:08] Borrado /media/discousb/Descargas/temp/uno/2.zipx
[30-10-2024 20:08] Borrado /media/discousb/Descargas/2.zipx
y los archivos sospechosos al péo... :xd

Gracias de nuevo. He aprendido mucho. :sii :sii
Última edición por MuadDib69 el 31 Oct 2024, 17:27, editado 1 vez en total.
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

Perfecto, ¡buen trabajo!
¡Bash power!
Estos usuarios agradecieron al autor egrueda por el mensaje:
MuadDib69
Responder