100

If I wanted to create multiple directories (on the same level) and then feed it a comma seperated list of directory names (or something to that effect)?

  • 38
    man mkdir.... – Sparhawk Feb 10 '16 at 9:30
  • 5
    Any time you want to know if a command can do some thing you want done, type man followed by the name of the command. – David Richerby Feb 10 '16 at 18:22
  • @DavidRicherby although man mkdir "kind of" suggests the possibility to create multiple directories at once, it is not mentioned specifically, nor how to do that. – Jacob Vlijm Feb 10 '16 at 21:19
  • 2
    @JacobVlijm The GNU coreutils 8.21 manpage for mkdir says, "NAME mkdir - make directories // SYNOPSIS mkdir [OPTION]... [DIRECTORY]... // DESCRIPTION Create the DIRECTORY(ies) if they do not already exist." That seems pretty clear that you can make more than one directory. – David Richerby Feb 10 '16 at 22:20
  • 9
    @JacobVlijm Man pages jargon is not obvious without instruction, but in the technical language of man pages, the info is totally clear, even in the given quote. Note the ... after [DIRECTORY], meaning that argument can be repeated. So DIRECTORY(ies) refers to all passed DIRECTORY arguments. However, "RTFM" comments sometimes forget there is a notation to learn. – Blaisorblade Feb 11 '16 at 18:51
141

Short answer

mkdir takes multiple arguments, simply run

mkdir dir_1 dir_2
145

You can use lists to create directories and it can get pretty wild.

Some examples to get people thinking about it:

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 directories from sa1 through sa50
  2. same but each of the directories will hold 50 times sax1 through sax50 (-p will create parent directories if they do not exist.
  3. 26 directories from a12345 through z12345
  4. comma separated list makes dirs 1, 2 and 3.
  5. 10 directories from test01 through test10.
  6. same as 4 but with the current date as a directory and 1,2,3 in it.
  7. same as 4 but with the current user as a directory and 1,2,3 in it.

So, if I understood it correctly and you want to create some directories, and within them new directories, then you could do this:

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

and get sa1, sa2,...,sa10 and within each dirs 1, 2 and 3.

  • I agree with @gniourf_gniourf… there are no usages of regular expressions in your answer. Did you mean to say something else, or to provide a different example? – Slipp D. Thompson Feb 10 '16 at 4:02
  • 1
    @gniourf_gniourf done :) – Rinzwind Feb 10 '16 at 7:35
  • 3
    It is worth mentioning that brace expansion in not defined in the POSIX shell: pubs.opengroup.org/onlinepubs/9699919799/utilities/… For example it will not work in dash which is the default /bin/sh on Ubuntu. – pabouk Feb 10 '16 at 9:19
  • 7
    This answer depends on the shell doing expansion of your input before providing that input as arguments to mkdir. It's much more accurate to just say that mkdir can create multiple dirs with multiple arguments and then talk about how a given shell can make that easier. – deed02392 Feb 11 '16 at 5:55
  • If I try to do something like mkdir sa$(seq 0.1 0.1 1), all it does is create one directory named sa0.1 and the rest 0.2, 0.3, ..., 1. How can I get decimal brace expansion without writing the entire list? – Plinth Jan 3 '17 at 23:57
23

It's very simple, lets you want to create a directory structure such as:

Websites/
  static/
      cs
      js
  templates/
      html

You can do it in a single command like this:

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

Be careful not to enter any spaces

  • You can also press tab here to expand them before running the command. – Isaac Gregson Mar 25 '17 at 3:42
14

Make a list of the names for your desired directories using line breaks instead of commas as a separator. Save that list.

mkdir `cat list`

You should now have all the directories named in your list.

  • 1
    Yes, that will work, however , with a caveat - the directory names have to be one whole string. If one line is spaced dir , then it will create two dirs , spaced and `dir. – Sergiy Kolodyazhnyy Feb 10 '16 at 18:41
  • Yeah - you can't even successfully do any kind of escaping for the spaces, either - junk\ dir in the list file gives two directories, junk\ and dir. Gave me a panic when I saw a \ in a directory name. – Jon V Feb 11 '16 at 0:02
  • This can be combined with the -p flag mentioned in other answers. If so, the list file doesn't have to include parent directories as their own lines, they will be detected and made automatically. – mcw0933 Jul 20 '18 at 14:19
8

Something like this? (thanks to muru for the printf tip)

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

You can wrap it into a function for ease of use:

function mkdir_cs {
    printf '%s' "$1" | xargs -d, mkdir
}
$ ls
$ mkdir_cs 'foo,bar,baz'
$ ls
bar  baz  foo
$ 
  • 1
    Just a printf "%s" "$1" | xargs -d, mkdir should be enough. – muru Feb 9 '16 at 18:53
7

So you want comma separated list of directory names ? That can be done.

Shell + coreutils

Since everybody is posting oneliners, here's mine as well ( mkdir + parameter substitution plus + shell redirection ).

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

AWK is a text processing language, but it has very nice system() function which will call the default shell , and run command[s] enclosed in parenthesis ( which must be a string).

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

Or you could remove , with gsub() function, and call system("mkdir "$0) but that may be a problem if you want to create directories with spaces in their name

Python

Pythonic way of doing the same , would be to read each line, get rid of trailing \n , shove everything into one list, and iterate over the list items and create dirs per list item. Note that in the example bellow, /home/xieerqi/dirList.txt is the full path given to my file, and we make up full path of each new directory by joining string /home/username/ and the dir name read from list. Substitute your own values as necessary

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
    I don't think the asker actually wants the list to be comma-separated; I'm pretty sure that was just their guess at what the syntax might be. – David Richerby Feb 10 '16 at 18:23
  • Well, OP probably didn't to exactly have comma-separated list, however it's sure may be used as a method, point being " lists can be used,too, you don't have to type out name of each dir individually". Especially that will be useful when a big list cannot be generated with ranges, like dir{1..1000}. Say , you want to make a directory per username, or per project, or per geographic location, like a city – Sergiy Kolodyazhnyy Feb 10 '16 at 18:46
0

mkdir command takes multiple arguments simply run as below

mkdir dir1 dir2 dir3 ... dirN

If you would like to create multiple subdirectories then you can pass those argument in {} as shown below

mkdir dir1 dir2/{subdir1, subdir2, subdir3, subdirN} dir3 dirN

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.