Quindi fare qualcosa del genere in bash e la maggior parte delle altre shell non funzionerà per creare più sottodirectory o file all'interno di sottodirectory...
mkdir */test
touch */hello.txt
 
 Ovviamente ci sono molti modi per farlo, il mio preferito è usare find quando possibile invece di usare un for loop, principalmente per la leggibilità.
 Ma la mia domanda è, perché quanto sopra non funziona?
 Da quello che ho capito è perché il file/percorso di destinazione completo non esiste, ma sicuramente è una buona cosa se sto cercando di mkdir o touch . Sono sempre andato avanti e non l'ho mai veramente messo in discussione.
 Ma qualcuno ha una spiegazione decente per questo che mi aiuterà a capirlo una volta per tutte?
Risposta accettata:
 Il punto che potresti non notare – con cui molte persone hanno problemi,
 specialmente se hanno esperienza con altri sistemi operativi prima di arrivare a *nix
 – è che, in molti altri sistemi operativi, i caratteri jolly sul riga di comando sono normalmente passati al comando elaborare come meglio crede. Ad esempio, nel prompt dei comandi di Windows
rename *.jpeg *.jpg
 
 Considerando che, in *nix, per semplificare il lavoro
 del/i programmatore/i dei singoli comandi (es. mv ), i caratteri jolly
 (se non tra virgolette o con caratteri di escape) vengono gestiti dalla shell,
 in modo indipendente dall'interfaccia e dalla funzionalità
 del comando a cui i caratteri jolly sono argomenti. 
 La maggior parte dei programmi che accettano nomi di file come argomenti della riga di comando si aspettano che tali file esistano
 (sì, mkdir e touch sono eccezioni a questa regola,
 così come mkfifo , mknod e, in misura parziale, cp , ln , mv e rename;
 e probabilmente ce ne sono altri),
 quindi non ha davvero senso che la shell espanda i caratteri jolly
 in nomi di file che non esistono. 
 E per la shell (e, con questo, intendo ogni shell –
 Bourne, bash, csh, fish, ksh, zsh, ecc...) gestire le eccezioni in modo diverso
 sarebbe probabilmente una seccatura.
 Detto questo, ci sono un paio di modi per ottenere un risultato come quello che desideri. 
 Se sai a cosa si espanderà il carattere jolly,
 e non è lungo, puoi generarlo con l'espansione parentesi:
touch {red,orange,yellow,green,blue,indigo,violet}/rgb.txt
 Una soluzione più generale:
sh -c 'for arg do mkdir -- "$arg"/test; done' -- *
 
 Gilles mi ha aiutato a trovare un altro modo
 per farlo in bash.
benbradley=(*)
mkdir "${benbradley[@]/%//test}"
 
 Ovviamente benbradley è solo un identificatore qui; puoi usare qualsiasi nome
 (ad es. qualsiasi singola lettera). 
 Mi ci sono voluti un paio di tentativi per farlo bene, quindi lasciami scomporre:
identifier=valuecrea una variabile (scalare) denominataidentifier(se non esiste già) e assegna il valorevaluead esso.
Ad esempio,G=Man.
Puoi fare riferimento a una variabile scalare con$identifier;
ad esempio,$G, o, più sicuro, come${identifier}.
Ad esempio,$Gagee$Gillapotrebbe essere indefinito,
ma${G}ageèManagee${G}illaèManilla.identifier=(value1 value2 … )crea una variabile array denominataidentifier(se non esiste già) e gli assegna i valori elencati.
Ad esempio,
spectrum=(red orange yellow green blue indigo violet)
o
all_text_files=(*.txt)
 $name farà riferimento al primo elemento (e quindi è abbastanza inutile). 
 Puoi fare riferimento a un elemento arbitrario come ${name[subscript]};
 ad esempio, ${spectrum[0]} è red e ${spectrum[4]} è blue . 
 E puoi usare ${name[@]} e ${name[*]} per fare riferimento all'intero array.
Quindi, eccolo a pezzi:
"   ${   benbradley[@]   /   %   /   /test   }   " ${parameter/pattern/string}espande il${parameter}e sostituisce la corrispondenza più lunga
dipatternconstring.- Se 
patterninizia con#,
deve corrispondere all'inizio del valore espanso diparameter.
Sepatterninizia con%,
deve corrispondere alla fine del valore espanso diparameter.
In altre parole, 
%(the-rest_of_the_pattern)
si comporta come
(the-rest_of_the_regex)$
 (sì, sembra un po' indietro). 
 Quindi un pattern questo è solo un % è come un'espressione regolare che è solo un $ –
 corrisponde alla fine della stringa di input (spazio di ricerca).
- E sto usando una 
stringdi/test.
Quindi questo sostituisce la fine del parametro con/test(ovvero, aggiunge/testal parametro). - Un'altra cosa su 
${parameter/pattern/string}non è intuitivo è che sempre termina con un}.
Non è necessario e non può , termina con un terzo/.
Pertanto, un/instringnon può essere interpretato come un delimitatore,
e quindi possiamo avere unastringdi/testsenza bisogno di sfuggire al/. - Se 
parameterè una variabile array
con pedice@o*,
l'operazione di sostituzione viene applicata a turno a ciascun membro dell'array. - Quando fai riferimento a un array come 
${name[@]}(anziché${name[*]}) e inserisci i risultati tra virgolette,
mantieni l'integrità degli elementi dell'array
(ovvero, conservi gli spazi e altri caratteri speciali in essi)
senza combinare gli elementi separati in una parola lunga.