Spiega le opzioni -path e -prune di find


11

Ho un semplice script di cui capisco la maggior parte, è il comando find che non è chiaro. Ho molta documentazione, ma non serve a renderlo molto più chiaro. Il mio pensiero è che funzioni come un for-loop, il file attualmente trovato viene scambiato con {} e copiato in $ HOME / $ dir_name, ma come funziona la ricerca con -path e -prune -o ? È fastidioso avere una documentazione così specifica e pertinente e ancora non sapere cosa sta succedendo.

#!/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

Questa è solo la documentazione che so dovrei essere in grado di capire da.

modello di percorso

Il nome del file corrisponde al modello di conchiglia. I metacaratteri non trattano / o . appositamente; quindi, ad esempio, trova. -path "./sr*sc" stamperà una voce per una directory chiamata ./src/misc (se ne esiste una). Per ignorare un intero albero di directory, utilizzare -prune anziché controllare tutti i file nella struttura. Ad esempio, per saltare la directory src / emacs e tutti i file e le directory sottostanti e stampare i nomi degli altri file trovati, fare qualcosa del genere:

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

Dal manuale di Findutils

- Azione: comando -exec; Questa variante non sicura dell'azione -execdir è specificata da POSIX. La differenza principale è che il comando viene eseguito nella directory da cui è stato richiamato find , il che significa che {} viene espanso in un percorso relativo che inizia con il nome di una delle directory di partenza, anziché solo il nome di base del file corrispondente.

Mentre alcune implementazioni di find sostituiscono {} solo dove appare da solo in un argomento, GNU find sostituisce {} ovunque appaia.

E

Ad esempio, per confrontare ogni file di intestazione C nella o sotto la directory corrente con il file / tmp / master:

      find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'


Penso che qualcosa sia un duplicato di find-path spiegato anche se la risposta a find: prune non ignora il percorso specificato ha una risposta che sembra applicarsi a questa domanda. Forse le risposte spiegate del percorso di ricerca hanno senso per qualcuno che ha più esperienza con gli script, ma non mi aiutano. Le risposte qui presentate per me hanno più senso finora, anche se sto iniziando a esaminarle.
flerb,

Risposte:


23

-pathfunziona esattamente come -name, ma applica il modello all'intero percorso del file in esame, anziché all'ultimo componente.

-prune proibisce di scendere sotto il file trovato, nel caso fosse una directory.

Mettendo tutto insieme, il comando

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
  1. Inizia a cercare i file in $HOME.
  2. Se trova un file corrispondente $HOME/$dir_namenon andrà al di sotto di esso ("elimina" la sottodirectory).
  3. Altrimenti ( -o) se trova un file corrispondente lo *$file_suffixcopia in $HOME/$dir_name/.

L'idea sembra essere quella di fare un backup di alcuni dei contenuti di $HOMEuna sottodirectory di $HOME. Le parti con -prunesono ovviamente necessarie per evitare di fare backup dei backup ...


Se capisco allora: find eseguirà l'iterazione in ogni directory in $ HOME in cui ha le autorizzazioni per andare, tranne $ HOME / $ nome_dir, in cui non scenderà (perché l'azione della prugna verrà valutata come vera e non essere preso), cercando i file che terminano con $ file_suffix. Quindi non appena ne trova uno, eseguirà cp "found_file.sh" in $ HOME / $ dir_name? Inoltre, -path consente un percorso a un file ed è utile quando si desidera trovare discendere nelle directory e non solo lavorare nella directory corrente?
flerb,

La tua comprensione è quasi corretta. -pathfunziona come -name: seleziona i file. La differenza è che -nameabbina uno schema al nome del file, mentre -pathabbina uno schema al percorso completo. findscende sempre nelle sottodirectory, a meno che non sia impedito da -maxdeptho -pruneecc.
AlexP

Oh! -path viene applicato a $ HOME / $ dir_name -prune quindi, è l'ordine dei comandi che mi ha fatto confusione, e -path è necessario per il comando di eliminazione perché deve corrispondere al percorso completo della directory eliminata.
flerb

@Darren Non sono sicuro che sia abbastanza preciso. -path $HOME/$dir_nameè un'azione. È un test che verifica se il percorso del file corrente in esame corrisponde a qualunque cosa $HOME/$dir_namesia. -pruneè un'azione separata. Penso che la prima frase del tuo primo commento rifletta accuratamente come funziona.
David Z,

Mancherebbe qualcosa vederlo come una pipa? Ho scambiato -prune con -print e penso che il flusso sia chiaro ora: trova $ HOME | -path $ HOME / $ dir_name | -print
flerb

4

Fa parte del comando find, l'istruzione -exec.

Ti permette di interagire con il file / directory trovato dal findcomando.

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

find $HOME significa trovare file / directory in $ HOME

Per capire -path <some_path>, vedi `find -path` spiegato

Per capire -prune, vedi /programming/1489277/how-to-use-prune-option-of-find-in-sh

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

-exec significa eseguire il comando.

cp {} $HOME/$dir_name/ copia tutti i file corrispondenti a $HOME/$dir_name/

\;significa terminare il -execcomando

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.