/ / trova cartelle e cd in esse - bash, shell, find

trova cartelle e cd in esse - bash, shell, find

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 findma non so come fare l'azione per ogni linea findmi 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 № 1

Puoi 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.