texto recursivo por fecha ejemplos consola comandos comando buscar basicos archivos archivo bash grep find xargs

bash - recursivo - comando find unix



¿Cómo combino mi comando find y grep para eliminar los archivos? (4)

Actualmente tengo el siguiente comando que produce una lista de archivos:

find . -type f | grep -i -f ./remove_list

Este comando lee un archivo llamado "remove_list" que contiene una lista de términos (en realidad expresiones regex) que quiero encontrar en el resultado del comando find.

El comando anterior funciona bien pero no entiendo cómo eliminar ahora cada uno de los archivos encontrados (especialmente porque algunos de ellos contendrán espacios).

Pensé que podría hacer algo como esto:

find . -type f -print0 | grep -i -f ./remove_list | xargs -0 rm

Según tengo entendido, el -print0 y el -0 son necesarios para manejar nombres de archivos con espacios en ellos, pero ahora, cuando trato de ejecutar el comando, aparece un mensaje de error que dice "coincidencias de archivo binario (entrada estándar)".

¿Cómo leo en una cantidad de términos (regex) de un archivo para que puedan ser utilizados como argumentos en la declaración de búsqueda?


Si está usando GNU grep. Puedes usar -Z :

-Z, --null Output a zero byte (the ASCII NUL character) instead of the character that normally follows a file name. For example, grep -lZ outputs a zero byte after each file name instead of the usual newline. This option makes the output unambiguous, even in the presence of file names containing unusual characters like newlines. This option can be used with commands like find -print0, perl -0, sort -z, and xargs -0 to process arbitrary file names, even those that contain newline characters.

Y también necesita -z para la entrada.

-z, --null-data Treat the input as a set of lines, each terminated by a zero byte (the ASCII NUL character) instead of a newline. Like the -Z or --null option, this option can be used with commands like sort -z to process arbitrary file names.

Entonces su comando puede verse así:

find . -type f -print0 | grep -z -Z -i -f ./remove_list | xargs -0 rm


Si su primer comando encuentra todos los archivos, puede pasar la salida a través de un ciclo while para eliminar cada archivo.

find . -type f | grep -i -f ./remove_list | while read line; do rm "$line"; done


Solo necesita grep para generar una lista de archivos también. Grep no sabe que estos son archivos: simplemente los ve como una secuencia de datos. Si los archivos en sí mismos no tienen líneas nuevas en sus nombres y generalmente son seguros para espacios en blanco, entonces usted puede hacer:

find . -type f | grep -if ./remove_list | xargs rm

Los -print0 , --null y -0 a varios comandos son para prevenir errores debido a casos límite en los nombres de archivos, como nombres de archivos con múltiples espacios en blanco y nuevas líneas. El problema se vuelve más difícil si realmente tiene que lidiar con eso, porque su comando grep está tratando de filtrar los nombres por sí mismos. Si realmente necesita hacer eso, puede cambiar a una herramienta que pueda tratar cada nombre individualmente. En proyectiles con globbing recursivo (como bash 4):

shopt -s globstar for f in **/*; do # check if "$f" is a file and grep matches its name if [[ -f $f ]] && grep -qif ./remove_list <<< "$f"; then rm "$f" fi done

Como siempre, puedes imitar esto en find y un shell estándar con la misma lógica, pero algo más feo:

find . -type f -exec bash -c ''for f; do if printf ''%s/n'' "$f" | grep -qif ./remove_list; then rm "$f" fi done'' _ {} +


Si tiene GNU Parallel instalado:

find . -type f | grep -i -f ./remove_list | parallel rm

Si no está empaquetado para su sistema, debería instalarlo en 10 segundos:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

Para obtener más información: mire el video introductorio para obtener una introducción rápida: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Recorre el tutorial (man parallel_tutorial). Tu línea de comando te amará por eso.