212

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)?

Pabru
  • 255
BGroat
  • 2,295

8 Answers8

244

Short answer

mkdir takes multiple arguments, simply run

mkdir dir_1 dir_2
Jacob Vlijm
  • 83,767
230

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.

edwinksl
  • 23,789
Rinzwind
  • 299,756
  • 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 04:02
  • 1
    @gniourf_gniourf done :) – Rinzwind Feb 10 '16 at 07:35
  • 4
    It is worth mentioning that brace expansion in not defined in the POSIX shell: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06 For example it will not work in dash which is the default /bin/sh on Ubuntu. – pabouk - Ukraine stay strong Feb 10 '16 at 09:19
  • 10
    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 05:55
  • 1
    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 03 '17 at 23:57
  • man 1 seq or even better info seq are your friends. This will do the job:

    for f in $(seq -f %g 0.2 1 10) ; do mkdir -p test/$f ; done

    it will create a directory test with subdirs 0,2 up to 9,2 Note that my local is Dutch, if LC_TYPE is en_US you will get the dot as decimal separator. The key is that seq accepts printf syle formatting.

    – runlevel0 Feb 02 '17 at 13:17
  • I think you meant mkdir {a..z}12345 not mkdir {a-z}12345 – Dominic Motuka Jun 11 '18 at 09:37
  • Thanks you working file ..... – balaji Feb 13 '20 at 12:05
  • @Rinzwind just being curious, what is the difference between mkdir {1,2,3} and mkdir 1 2 3? practically both do the same, so when is mandatory the former? – Manuel Jordan Jan 06 '22 at 22:22
  • Shoot that works as well with touch to create files. – thoroc Dec 01 '23 at 08:22
  • 1
    @ManuelJordan ah the {1,2,3} is a simplified version. It becomes interesting when it is mkdir {1,2,3}a{3,4} then you get 1a3, 1a4, 2a3, 2a4 etc. – Rinzwind Dec 01 '23 at 09:08
68

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

Websites/
  static/
      cs
      js
  templates/
      html and xhtml

You can do it in a single command like this:

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

Be careful to escape the spaces in your directory names.

17

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.

  • 2
    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
  • 1
    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 00: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. – mcw Jul 20 '18 at 14:19
  • Make sure the 'list' file has no file ending. list.txt will result in the creation of the directory list.txt in the location of the file. And those are backticks, not single quotes: `cat list` not 'cat list'. – Mark Lee Jan 20 '22 at 02:50
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
$ 
kos
  • 35,891
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)
Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
  • 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
6

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 (use only commas to separate the argument, without spaces).

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

Using the option "-p" to make parent directories as needed.

djayor
  • 3
1

Simply use the -p argument:

mkdir -p app/code/Foo/Bar


This is what the help page says about -p. I would not understand it by that text...

-p, --parents no error if existing, make parent directories as needed

Black
  • 801