Explicar las opciones find -path y -prune

11

Tengo una secuencia de comandos simple que entiendo, es el comando de búsqueda que no está claro. Tengo mucha documentación, pero no sirve para que sea mucho más claro. Creo que funciona como un bucle for, el archivo encontrado actualmente se intercambia por {} y se copia a $ HOME / $ dir_name, pero ¿cómo funciona la búsqueda con -path y -prune -o ? Es molesto tener una documentación tan específica y relevante y aún no saber qué está pasando.

#!/bin/bash
# The files will be search on from the user's home
# directory and can only be backed up to a directory
# within $HOME

read -p "Which file types do you want to backup " file_suffix
read -p "Which directory do you want to backup to " dir_name

# The next lines creates the directory if it does not exist
test -d $HOME/$dir_name || mkdir -m 700 $HOME/$dir_name

# The find command will copy files that match the
# search criteria ie .sh . The -path, -prune and -o
# options are to exclude the backdirectory from the
# backup.
find $HOME -path $HOME/$dir_name -prune -o \
-name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
exit 0

Esta es solo la documentación de la que sé que debería poder resolver esto.

patrón de ruta

El nombre del archivo coincide con el patrón de concha. Los metacaracteres no tratan / o . especialmente; entonces, por ejemplo, encontrar. -path "./sr*sc" imprimirá una entrada para un directorio llamado ./src/misc (si existe). Para ignorar un árbol de directorios completo, use -prune en lugar de verificar cada archivo en el árbol. Por ejemplo, para omitir el directorio src / emacs y todos los archivos y directorios que contiene, e imprimir los nombres de los otros archivos encontrados, haga algo como esto:

find . -path ./src/emacs -prune -o -print

Del manual de Findutils

- Acción: comando -exec; POSIX especifica esta variante insegura de la acción -execdir . La principal diferencia es que el comando se ejecuta en el directorio desde el que se invocó find , lo que significa que {} se expande a una ruta relativa que comienza con el nombre de uno de los directorios de inicio, en lugar de solo el nombre base del archivo coincidente.

Mientras que algunas implementaciones de find reemplazan {} solo donde aparece solo en un argumento, GNU find reemplaza {} donde sea que aparezca.

Y

Por ejemplo, para comparar cada archivo de encabezado C en o debajo del directorio actual con el archivo / tmp / master:

      find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'
flerb
fuente
Posible duplicado de find: prune no ignora la ruta especificada
thecarpy
Creo que, en todo caso, es un duplicado de find-path explicado incluso si la respuesta en find: prune no ignora la ruta especificada tiene una respuesta que parece aplicarse a esta pregunta. Tal vez las respuestas explicadas de find-path tengan sentido para alguien más experimentado con scripting, pero no me ayudan. Las respuestas presentes aquí tienen más sentido para mí hasta ahora, a pesar de que estoy empezando a analizarlas.
flerb

Respuestas:

23

-pathfunciona exactamente igual -name, pero aplica el patrón a la ruta completa del archivo que se está examinando, en lugar de al último componente.

-prune prohíbe descender debajo del archivo encontrado, en caso de que fuera un directorio.

Poniendo todo junto, el comando

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
  1. Comienza a buscar archivos en $HOME.
  2. Si encuentra un archivo que coincida $HOME/$dir_name, no irá debajo de él ("elimina" el subdirectorio).
  3. De lo contrario ( -o) si encuentra un archivo que coincida, lo *$file_suffixcopia $HOME/$dir_name/.

La idea parece ser hacer una copia de seguridad de algunos de los contenidos de $HOMEun subdirectorio de $HOME. -pruneObviamente, las partes con son necesarias para evitar hacer copias de seguridad de las copias de seguridad ...

AlexP
fuente
Si entiendo entonces: find iterará a través de todos y cada uno de los directorios en $ HOME que tiene permisos para entrar, excepto $ HOME / $ dir_name, en el que no descenderá (porque la acción de poda se evaluará como verdadera y la o no se tomará), buscando archivos que terminen con $ file_suffix. Luego, tan pronto como encuentre uno, ejecutará cp "found_file.sh" en $ HOME / $ dir_name? Además, -path permite una ruta a un archivo y es útil cuando desea que descienda a los directorios y no solo trabaje en el directorio actual.
flerb
Tu comprensión es casi correcta. -pathfunciona igual que -name: selecciona archivos. La diferencia es que hace -namecoincidir un patrón con el nombre del archivo, mientras que hace -pathcoincidir un patrón con el nombre completo de la ruta. findsiempre desciende a subdirectorios, a menos que sea impedido por -maxdeptho -pruneetc.
AlexP
Oh! -path se está aplicando a $ HOME / $ dir_name -prune entonces, es el orden de los comandos lo que me estaba confundiendo, y -path es necesario para el comando podar porque necesita coincidir con la ruta completa del directorio podado.
flerb
@Darren, no estoy seguro de si eso es bastante exacto. -path $HOME/$dir_nameEs una acción. Es una prueba que verifica si la ruta del archivo actual que se está examinando coincide con lo que $HOME/$dir_namesea. -pruneEs una acción separada. Creo que la primera oración de tu primer comentario refleja con precisión cómo funciona eso.
David Z
¿Le faltaría algo para verlo como una tubería? Cambié -prune por -print y creo que el flujo es claro ahora: encuentre $ HOME | -path $ HOME / $ dir_name | -print
flerb
4

Es parte del comando find, la instrucción -exec.

Le permite interactuar con el archivo / directorio encontrado por el findcomando.

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;

find $HOME significa buscar archivos / directorios en $ HOME

Para entender -path <some_path>, vea `find -path` explicado

Para comprender -prune, consulte /programming/1489277/how-to-use-prune-option-of-find-in-sh

-osignifica OR, entonces -path <some_path>OR-name *$file_suffix

-exec significa ejecutar el comando.

cp {} $HOME/$dir_name/ copie cualquier archivo que coincida con $HOME/$dir_name/

\;significa terminar el -execcomando

thecarpy
fuente