Come faccio a creare una directory in tutte le sottodirectory?


34

Supponiamo che io abbia una struttura di directory come questa:

$ [~ / practice] ls
a / b / c / d /

Ora voglio creare una directory tmp1in tutte le sottodirectory di practicee faccio questo:

$ [~ / practice] mkdir * / tmp1
mkdir: impossibile creare la directory `* / tmp1 ': nessun file o directory

Quindi provo l' -pinterruttore e finisco con una directory denominata *con una sottodirectorytmp1

$ [~ / practice] mkdir -p * / tmp1

$ [~ / practice] ls
* / a / b / c / d /

So che l'uso di -pswitch è di creare più directory inesistenti. Ho solo pensato che potesse aiutare.

Come posso creare tmp1in tutte le sottodirectory contemporaneamente?

Se questo può essere fatto, come faccio estendo a creare \tmp1, \tmp2, \tmp3a \a, \be \cin una volta?

Edit: mi mancava di ricordare che le directory non devono essere semplici e in ordine, come a, b, cecc, e la directory da creare non è necessariamente come tmp1, tmp2.

$ [~ / practice] ls
cane / gatto / ratto /

In loro, vorrei avere qualcosa di simile

$ [~ / practice] ls *
cane:
rosso blu/

gatto:
rosso blu/

ratto:
rosso blu/

1
Data la risposta di Christopher , dovresti chiarire se "create \ tmp1, \ tmp2, \ tmp3 in \ a, \ b e \ c" dovrebbe risultare in un totale di 3 o 9 sottodirectory.
arte

@manatwork: è un buon punto. Dovrebbe creare 9 sottodirectory.
Animesh,

Questo è il mio aiuto per risolvere il problema di spazio nel nome della directory sudo find ./ -depth -type d -exec echo '"{} / RCS"' \;

Risposte:


44

Con globs :

for dir in */; do mkdir -- "$dir/tmp1"; done

NOTA

  • Tratto solo dir (compresi i collegamenti simbolici a dir) con il piccolo trucco di usare */come glob
  • Se vuoi creare più sottodir in una volta:

    for dir in */; do mkdir -- "$dir"/{tmp1,foo,bar,qux}; done


Posso fare for i in */; do mkdir "$i/itemone" "$i/itemtwo"; doneper più nomi di directory non in ordine?
Animesh,

Ho provato questo ed è molto possibile. Grazie.
Animesh,

Vedi il mio post modificato
Gilles Quenot,

1
L'espansione del controvento non viene eseguita nella stringa tra virgolette.
arte

Sì, grazie, post pubblicato da Stephane Chazelas di conseguenza ...
Gilles Quenot,

10

[...] come posso estenderlo per creare contemporaneamente \ tmp1, \ tmp2, \ tmp3 in \ a, \ b e \ c?

 mkdir {a,b,c}/tmp{1,2,3}

10

Con GNU o BSD * trova:

find -mindepth 1 -maxdepth 1 -type d -exec mkdir {}/newdir \;

o usando l'espansione dei parametri:

dirs=(*/)
mkdir -- "${dirs[@]/%/newdir}"

* Include OS X


2
Con la sintassi di ricerca standard:find . -name . -o -prune -type d -exec sh -c 'exec mkdir "$1/newdir"' sh {} \;
Stéphane Chazelas,

1
Notare anche le differenze tra le due soluzioni: la prima include directory nascoste, la seconda aggiungerà un newdir nelle directory collegate da qualsiasi collegamento simbolico nella directory corrente.
Stéphane Chazelas,

6

Fuori tema dal momento che stai citando bash, ma per la cronaca, con zsh, dovresti fare:

dirs=(*(/))
mkdir -- $^dirs/tmp1

$^varattiva l'espansione di tipo parentesi graffa per l'espansione dell'array. Ricorda rcl' ^operatore di e in rc(o il suo derivato es), lo scriveresti:

dirs=(*/)
mkdir -- $dirs^tmp1

Tuttavia nota (e lo stesso vale per le soluzioni bash fornite qui) che nella soluzione rc dirsconterrebbe anche collegamenti simbolici alle directory. Nella soluzione zsh, cambia *(/)in *(-/)se vuoi includere collegamenti simbolici alle directory.


+1 per il tuo punto sui symlink! Questo comportamento può essere desiderato, ma il reclamo di mkdir sulla creazione di una directory duplicata può essere eliminato con il -pflag.
Kojiro,

4

Portabilmente, scorrere le directory principali:

for d in */; do mkdir "$d/red" "$d/blue"; done

Aggiungi --dopo mkdirse potresti avere directory il cui nome inizia con -.

In zsh, puoi farlo in un singolo comando con il e qualificatore glob :

mkdir *(/e\''REPLY=($REPLY/{red,blue})'\')

ma è più veloce digitare questo come due comandi:

d=(*(/)); mkdir $^d/{red,blue}

1
Su un sito che dovrebbe essere un riferimento, preferirei dire " mkdir -- whatever, e ometterei -- se intendi l'espansione di qualsiasi cosa possa essere presa come opzione per il mkdircomando". Non ha senso omettere --qui. Potrebbe non essere un problema nel caso del PO, ma lo è nel caso generale. Penso che abbiamo il dovere di insegnare la sintassi corretta e sicura qui.
Stéphane Chazelas,

@StephaneChazelas In un contesto di scripting, ho sempre messo tutto ciò che è necessario --e citazioni e grossi avvertimenti quando le newline non sono supportate. In un contesto da riga di comando, preferisco mostrare la versione rapida che funziona prima in pratica e la versione a prova di proiettile come complemento.
Gilles 'SO- smetti di essere malvagio' il


1

Variazione sulla risposta di sputnick che evita i file non di directory:

for x in *; do if [ -d "$x" ]; then mkdir "$x/tmp1"; fi; done

Tratto solo dir, questa è tutta la magia ...
Gilles Quenot

cool, capito;)
goldilocks

2
Non dovrebbe essere if [ -d "$x" ];…?
Kojiro

Sì. Praticamente non ho mai spazi nei nomi dei file e tendo a dimenticare quella roba ...
goldilocks

1

Questo è buono dai vecchi Unix Masters (testati su FreeBSD 10.1) se vuoi controllare la versione (con il controllo RCS bloccato: ci -l con un breve commento come ir: per la versione iniziale) i tuoi file di configurazione / etc / * su ~ / .his / ecc

sudo rsync -av /etc/ ~/.his
sudo find -d ~/.his/etc -type d -exec echo '{}/RCS' \; | xargs sudo mkdir -p
sudo find -d ~/.his/etc \! -name "RCS" | xargs sudo ci -l -mir -t-ir

Non riesco a vedere come questa risposta OP
Archemar il

1

Dovrebbe essere \! nome "RCS" e funziona meglio al primo check in.

sudo find ~ / .his / etc \! -name "RCS" -ls

sudo find -d ~ / .his / etc \! -name "RCS" | xargs sudo ci -l -mir -t-ir

Quest'ultimo funziona anche molto bene per il cjeck in parte filtrando tutto il contenuto RCS sul nome del file:

sudo find -d ~ / .his / etc -type f | grep -v RCS | xargs sudo ci -l -mir -t-ir


1

questo mi è di grande aiuto. ho avuto la necessità di creare una serie di sottodirectory in più cartelle e qualcosa di simile:

!/bin/sh

cd /dest/cont

for dir in */*/; do
    mkdir -p -- $dir/{FB,Video,Audio,proj};
done

ha funzionato alla grande tranne quando si incontra uno spazio bianco. c'è un modo per ignorare gli spazi nella */*/parte degli argomenti?

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.