Volevo scrivere una breve sceneggiatura con la seguente struttura:
find the right folders
cd into them
replace an item
Quindi il mio problema è che ottengo le cartelle giuste da find
ma non so come fare l'azione per ogni linea find
mi sta dando. L'ho provato con un ciclo for in questo modo:
for item in $(find command)
do magic for item
done
ma il problema è che questo comando stamperà i relativi percorsi e, se c'è uno spazio nel mio percorso, dividerà il percorso in questo punto.
Spero che tu abbia capito il mio problema e che mi possa dare un suggerimento.
risposte:
2 per risposta № 1Puoi eseguire comandi con l'opzione -exec di find direttamente:
find . -name some_name -exec your_command {} ;
1 per risposta № 2
Un modo per farlo è:
find command -print0 |
while IFS= read -r -d "" item ; do
... "$item" ...
done
-print0
e read ... -d ""
fa sì che il carattere NUL venga utilizzato per separare i percorsi e assicurarsi che il codice funzioni per tutti i percorsi, inclusi quelli che contengono spazi e newline. Ambientazione IFS
svuotare e usare il -r
opzione a read
impedisce che i percorsi vengano modificati da read
.
Si noti che il while
il ciclo viene eseguito in una subshell, quindi le variabili impostate al suo interno non saranno visibili al termine del ciclo. Se questo è un problema, un modo per risolverlo è utilizzare la sostituzione del processo anziché una pipe:
while IFS= ...
...
done < <(find command -print0)
Un'altra opzione, se hai Bash 4.2 o successivo, è usare il lastpipe
opzione (shopt -s lastpipe
) per eseguire l'ultimo comando nelle pipeline nella shell corrente.
0 per risposta № 3
Se il modello che vuoi trovare è abbastanza semplice e hai bash 4, potresti non averne bisogno find
. In tal caso, potresti usare globstar
invece per globbing ricorsivo:
#!/bin/bash
shopt -s globstar
for directory in **/*pattern*/; do
(
cd "$directory"
do stuff
)
done
Le parentesi rendono possibile ogni operazione in una subshell. Ciò può avere un costo in termini di prestazioni, ma di solito non lo è, e significa che non devi ricordartelo cd
indietro ogni volta.
Se globstar
non è un'opzione (perché il tuo find
le istruzioni non sono un modello semplice, o perché non hai una shell che lo supporta) che puoi usare find
in un modo simile:
find . -whatever -exec bash -c "cd "$1" && do stuff" _ {} ;
Potresti usare +
invece di ;
per passare più argomenti a bash ogni volta, ma facendo una directory per shell (che è cosa ;
farebbe) ha benefici e costi simili all'utilizzo dell'espressione di sottoshell sopra.