Per ogni file corrispondente (ovvero ogni directory), find
passa alla directory che lo contiene (ovvero la directory principale) ed esegue il comando specificato. Poiché il comando non utilizza il nome della corrispondenza, non agirà mai su tutte le directory. Per questo particolare albero di directory, lo stai facendo
(cd . && touch foo) # because ./a matches
(cd ./a && touch foo) # because ./a/b matches
(cd ./a/b && touch foo) # because ./a/b/c matches
Per creare un file in ogni directory, puoi semplicemente usare -exec
invece di -execdir
, a condizione che la tua implementazione di find
permette {}
all'interno di un argomento (la maggior parte lo fa, e in particolare penso tutti quelli):
find . -type d -exec touch {}/foo +
Per la portabilità POSIX, è necessario eseguire manualmente l'assemblaggio del nome della directory e del nome della base file.
find . -type d -exec sh -c 'touch "$0/foo"' {} \;
o (leggermente più veloce)
find . -type d -exec sh -c 'for d; do touch "$d/foo"; done' _ {} +
In alternativa, è possibile utilizzare la corrispondenza jolly ricorsiva di bash. Fai attenzione che (a differenza della funzione corrispondente in ksh e zsh, e diversamente dal tuo find
comando) bash reclute sotto collegamenti simbolici alle directory.
shopt -s globstar
for d in **/*/; do touch -- "$d/foo"; done
Una soluzione zsh:
touch ./**/(e\''REPLY+=foo'\')
man bash
stati in "-c": gli argomenti dopo command_string sono assegnati a parametri posizionali che iniziano con $ 0, tuttavia "per d" ripeterà i parametri posizionali che iniziano con $ 1. "_" è un testo assegnato a $ 0 e non verrà utilizzato.