Existe uma maneira de criar vários diretórios ao mesmo tempo com o mkdir?


112

Se eu quisesse criar vários diretórios (no mesmo nível) e depois alimentá-lo com uma lista separada por vírgulas de nomes de diretórios (ou algo nesse sentido)?


38
man mkdir....
Sparhawk

5
Sempre que desejar saber se um comando pode fazer algo que você deseja, digite manseguido do nome do comando.
David Richerby

@DavidRicherby embora man mkdir"tipo de" sugira a possibilidade de criar vários diretórios de uma vez, não é mencionado especificamente, nem como fazer isso.
Jacob Vlijm

2
@JacobVlijm A página de manual do GNU coreutils 8.21 para mkdir diz: " NOME mkdir - faça diretórios // SINOPSE mkdir [OPÇÃO] ... [DIRETÓRIO] ... // DESCRIÇÃO Crie o (s) DIRETÓRIO (s), se ele ainda não existir". Parece claro que você pode criar mais de um diretório.
David Richerby

9
O jargão das páginas de manual do @JacobVlijm não é óbvio sem instruções, mas na linguagem técnica das páginas de manual, as informações são totalmente claras, mesmo na citação fornecida. Observe o ...depois [DIRECTORY], significando que o argumento pode ser repetido. Portanto, DIRECTORY(ies)refere-se a todos os DIRECTORYargumentos passados . No entanto, os comentários "RTFM" às vezes esquecem que existe uma notação a ser aprendida.
Blaisorblade

Respostas:


147

Resposta curta

mkdir recebe vários argumentos, basta executar

mkdir dir_1 dir_2

152

Você pode usar listas para criar diretórios e isso pode ficar bem selvagem.

Alguns exemplos para fazer as pessoas pensarem sobre isso:

mkdir sa{1..50}
mkdir -p sa{1..50}/sax{1..50}
mkdir {a-z}12345 
mkdir {1,2,3}
mkdir test{01..10}
mkdir -p `date '+%y%m%d'`/{1,2,3} 
mkdir -p $USER/{1,2,3} 
  1. 50 diretórios de sa1 a sa50
  2. mesmo, mas cada um dos diretórios conterá 50 vezes sax1 a sax50 (-p criará diretórios pai se eles não existirem.
  3. 26 diretórios de a12345 a z12345
  4. lista separada por vírgula cria dirs 1, 2 e 3.
  5. 10 diretórios de test01até test10.
  6. igual a 4, mas com a data atual como um diretório e 1,2,3 nele.
  7. igual a 4, mas com o usuário atual como um diretório e 1,2,3 nele.

Então, se eu entendi direito e você deseja criar alguns diretórios e, dentro deles, novos diretórios, você pode fazer o seguinte:

mkdir -p sa{1..10}/{1,2,3}

e obtenha sa1, sa2, ..., sa10 e dentro de cada dirs 1, 2 e 3.


Concordo com @ gniourf_gniourf… não há uso de expressões regulares em sua resposta. Você quis dizer outra coisa ou fornecer um exemplo diferente?
Slipp D. Thompson

1
@gniourf_gniourf done :)
Rinzwind

3
Vale ressaltar que a expansão de chaves não está definida no shell do POSIX: pubs.opengroup.org/onlinepubs/9699919799/utilities/… Por exemplo, não funcionará no dashpadrão /bin/shdo Ubuntu.
pabouk

7
Essa resposta depende do shell fazer a expansão da sua entrada antes de fornecer essa entrada como argumento para o mkdir . É muito mais preciso dizer apenas que o mkdir pode criar vários diretórios com vários argumentos e depois falar sobre como um determinado shell pode facilitar isso.
deed02392

Se eu tentar fazer algo assim mkdir sa$(seq 0.1 0.1 1), tudo o que ele faz é criar um diretório chamado sa0.1 e o restante 0.2, 0.3, ..., 1. Como posso obter expansão de chaves decimais sem escrever a lista inteira?
Plinth

26

É muito simples, permite criar uma estrutura de diretórios como:

Websites/
  static/
      cs
      js
  templates/
      html

Você pode fazer isso em um único comando como este:

mkdir -p Website/{static/{cs,js},templates/html}

Cuidado para não entrar em nenhum espaço


Você também pode pressionar tab aqui para expandi-los antes de executar o comando.
Isaac Gregson

14

Faça uma lista dos nomes para os diretórios desejados usando quebras de linha em vez de vírgulas como separador. Salve essa lista.

mkdir `cat list`

Agora você deve ter todos os diretórios nomeados em sua lista.


1
Sim, isso funcionará, no entanto, com uma ressalva - os nomes dos diretórios devem ser uma sequência inteira. Se uma linha for spaced dir, ela criará duas direções spacede `dir.
Sergiy Kolodyazhnyy

Sim - você também não pode fazer nenhum tipo de escape pelos espaços - junk\ dirno listarquivo fornece dois diretórios junk\ e dir. Fiquei em pânico quando vi um \ nome de diretório.
Jon V

Isso pode ser combinado com a -pbandeira mencionada em outras respostas. Nesse caso, o listarquivo não precisa incluir os diretórios pai como suas próprias linhas, eles serão detectados e criados automaticamente.
Mcw0933

8

Algo assim? (graças a muru pela printfdica)

printf '%s' 'foo,bar,baz' | xargs -d, mkdir
$ ls
$ printf '%s' 'foo,bar,baz' | xargs -d, mkdir
$ ls
bar  baz  foo
$ 

Você pode agrupá-lo em uma função para facilitar o uso:

function mkdir_cs {
    printf '%s' "$1" | xargs -d, mkdir
}
$ ls
$ mkdir_cs 'foo,bar,baz'
$ ls
bar  baz  foo
$ 

1
Apenas um printf "%s" "$1" | xargs -d, mkdirdeve ser suficiente.
muru

7

Então você quer uma lista separada por vírgula de nomes de diretório? Isso pode ser feito.

Shell + coreutils

Como todo mundo está postando oneliners, aqui está o meu também (mkdir + substituição de parâmetro mais + redirecionamento de shell).

DIR:/testdir
skolodya@ubuntu:$ ls

DIR:/testdir
skolodya@ubuntu:$ mkdir $( tr '[,\n]' ' '   < /home/xieerqi/dirList.txt   )                                           

DIR:/testdir
skolodya@ubuntu:$ ls
dirFive/  dirfour/  dirone/  dirthree/  dirtwo/

AWK

O AWK é uma linguagem de processamento de texto, mas possui uma system()função muito interessante que chamará o shell padrão e executará comandos entre parênteses (que devem ser uma sequência).

DIR:/xieerqi
skolodya@ubuntu:$ awk -F ',' '{for(i=1;i<=NF;i++) system("mkdir "$i)}' dirList.txt                                    

DIR:/xieerqi
skolodya@ubuntu:$ ls -ld dir*                                                                                         
-rw-rw-r-- 1 xieerqi xieerqi   23 Feb  9 11:41 dirList.txt
drwxrwxr-x 2 xieerqi xieerqi 4096 Feb  9 11:42 dirone/
drwxrwxr-x 2 xieerqi xieerqi 4096 Feb  9 11:42 dirthree/
drwxrwxr-x 2 xieerqi xieerqi 4096 Feb  9 11:42 dirtwo/

DIR:/xieerqi
skolodya@ubuntu:$ cat dirList.txt                                                                                     
dirone,dirtwo,dirthree

Ou você pode remover ,com gsub()function e chamar, system("mkdir "$0)mas isso pode ser um problema se você deseja criar diretórios com espaços em seus nomes

Pitão

A maneira pitônica de fazer o mesmo seria ler cada linha, livrar-se do final \n, colocar tudo em uma lista e iterar sobre os itens da lista e criar diretórios por item da lista. Observe que, no exemplo abaixo, /home/xieerqi/dirList.txté o caminho completo fornecido ao meu arquivo, e criamos o caminho completo de cada novo diretório juntando string /home/username/e o nome do diretório lido na lista. Substitua seus próprios valores conforme necessário

DIR:/testdir
skolodya@ubuntu:$ ls                                                                                                  

DIR:/testdir
skolodya@ubuntu:$ /home/xieerqi/makeDirs.py                                                                           

DIR:/testdir
skolodya@ubuntu:$ ls
dirFive/  dirfour/  dirone/  dirthree/  dirtwo/

DIR:/testdir
skolodya@ubuntu:$ cat /home/xieerqi/makeDirs.py
#!/usr/bin/env python
import os
with open("/home/xieerqi/dirList.txt") as file:
   for line in file:
         for directory in line.strip().rsplit(','):
             path = '/home/xieerqi/testdir/' +  directory
             os.makedirs(path)

3
Eu não acho que o solicitante realmente queira que a lista seja separada por vírgulas; Tenho certeza de que esse foi apenas o palpite sobre qual poderia ser a sintaxe.
David Richerby

Bem, o OP provavelmente não tinha exatamente uma lista separada por vírgula, no entanto, com certeza pode ser usado como um método, sendo que "as listas também podem ser usadas, você não precisa digitar o nome de cada dir individualmente". Especialmente isso será útil quando uma grande lista não puder ser gerada com intervalos, como dir{1..1000}. Digamos, você deseja criar um diretório por nome de usuário, projeto ou localização geográfica, como uma cidade
Sergiy Kolodyazhnyy

1

O comando mkdir usa vários argumentos, basta executar como abaixo

mkdir dir1 dir2 dir3 ... dirN

Se você deseja criar vários subdiretórios, pode passar esses argumentos em {}, como mostrado abaixo (use apenas vírgulas para separar o argumento, sem espaços).

mkdir dir1 dir2/{subdir1,subdir2,subdir3,subdirN} dir3 dirN
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.