Uso dell'espansione dei parametri per generare un elenco di argomenti per `mkdir -p`


10

Ho qualcosa del genere:

% ls -1dF /tmp/foo/*
/tmp/foo/000f9e956feab3ee4625aebb65ae7bae9533cdbc/
/tmp/foo/002e34c2218f2c86fefd2876f0e5c2559c5fb3c4/
/tmp/foo/00b483576791bab751e6cb7ee0a7143af43a8069/
.
.
.
/tmp/foo/fedd0f7b545e7ae9600142656756456bc16874d3/
/tmp/foo/ff51ac87609012137cfcb02f36624f81cdc10788/
/tmp/foo/ff8b983a7411395344cad64182cb17e7cdefa55e/

Voglio creare una directory barin ciascuna delle sottodirectory in foo.

Se provo a farlo con

% mkdir -p /tmp/foo/*/bar

... ottengo l'errore

zsh: no matches found: /tmp/foo/*/bar

(Con il senno di poi, posso capire il motivo dell'errore.)

So che posso risolvere il problema originale con un ciclo for, ma sono curioso di sapere se zshsupporta una qualche forma di espansione dei parametri che produrrebbe l'argomento desiderato per una singola invocazione di mkdir -p. IOW, un'espansione dei parametri equivalente a "aggiungi /bara ogni prefisso generato dall'espansione /tmp/foo/*", risultante

% mkdir -p /tmp/foo/000f9e956feab3ee4625aebb65ae7bae9533cdbc/bar ... /tmp/foo/ff8b983a7411395344cad64182cb17e7cdefa55e/bar

Risposte:


13
setopt histsubstpattern extendedglob
mkdir -p /tmp/foo/*(#q/:s_%_/bar_)

Si tratta di un globbing esteso che ha una bandiera globq uiet che usa un qualificatore glob per abbinare solo le directory e un modificatore per eseguire un ubstitution (usando il carattere pattern che è disponibile solo nella modalità pattern di sostituzione della cronologia ) che aggiunge una stringa a ogni parola.s%

man zshexpn

Wow, sono impressionato. Ho anche trovato tutto nella pagina man che specifichi.
Wildcard l'

1
Si noti che il poster originale specificato mkdir -p, che avrebbe l'effetto leggermente diverso dal comando di non generare errori se alcune di quelle directory hanno già delle barsottodirectory. Punto minore ma vale la pena notare qui. :)
Wildcard l'

1
Un altro modo è quello di utilizzare l'espansione dell'array tramite ${^spec}e accodare bara ciascun elemento di ciò che si /tmp/foo/*(/)espande in: set -- /tmp/foo/*(/)thenmkdir -p -- "${^@}/bar"
don_crissti

5

Sicuro: usa un anello

for n in /tmp/foo/*; do mkdir "$n/bar";done

globs sono usati per espandere elenchi di oggetti esistenti , non cose che non sono ancora state create.


Mi dispiace, temo che la mia domanda non sia stata chiaramente espressa. Lo chiarirò.
kjo,

2
Questo non risponde se è zshpossibile espandere globs e aggiungere testo con una sola sintassi, ma penso che sia probabilmente l'unico modo per fare quello che vuoi, @kjo.
Wildcard l'

4

Se le directory sono in un array, è possibile utilizzare la ${^...}forma di espansione.

a=(/tmp/foo/*/)
mkdir -p ${^a}bar

0

Puoi usare finde xargsper farlo:

find /tmp/foo -maxdepth 1 -mindepth 1 -type d | xargs -i echo mkdir -p {}/bar

che utilizza -maxdepth 1e -mindepth 1per impedire la creazione di barsottodirectory di target, e di per /tmp/foosé rispettivamente. type dfa considerare solo le directory.

È necessario rimuovere echoper eseguire azioni effettive, altrimenti echoverranno stampate solo le righe da eseguire. Puoi anche racchiuderlo in sostituzione come $()eseguirlo.

Il manuale dice che xargs -iè deprecato, ma non ho trovato altra alternativa altrettanto utile, quindi dovrebbe funzionare ancora per alcuni anni ... Puoi sostituirlo -icon -I'{}'per essere aggiornato con quello.


Questa risposta e la prossima mi stanno bene. Qualcuno può spiegare perché dovrebbero essere votati in ribasso? I voti negativi vanno bene, ma come possiamo imparare se non vengono fornite ragioni?
Joe,

È un'alternativa funzionante che non fa altro che ciò che l'OP ha chiesto. Mi batte.
loa_in_

Penso che sia una specie di parzialità che le risposte debbano avere cattive risposte, quindi il pregiudizio ha influito negativamente sulla mia reputazione.
loa_in_

Non mi piacciono i voti bassi inspiegabili, ma non ho visto alcun pregiudizio del genere. Di solito, le risposte "cattive" (quelle che ho capito) sono in realtà cattive.
Joe,

0

@loa_in_ ne aveva la maggior parte, ma l' findoutput delle tubazioni tende ad essere un passo falso.

find /tmp/foo -maxdepth 1 -mindepth 1 -type d -exec mkdir {}/bar \;

Uso solo xargsstrumenti diversi che non hanno -execalternative, quindi uso il mio approccio in quanto funziona allo stesso modo con tutti loro.
loa_in_
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.