Home > programming > Unix tip #1: advanced mkdir and brace expansion fun

Unix tip #1: advanced mkdir and brace expansion fun


If you don’t know all the ins and outs of the mkdir command, you are probably expending more effort than necessary.  Imagine this fairly common use case:

You are in a folder and want to create one folder which has 3 sub folders.  Let’s call the main folder Programming and its 3 sub folders Java, Python, and Scala.  Visually this looks like

or rendered via tree:

Programming/
|-- Java
|-- Python
`-- Scala

A first pass at accomplishing this would be to create the Programming folder, and then the three individual folders underneath

$ mkdir Programming
$ mkdir Programming/Java
$ mkdir Programming/Python
$ mkdir Programming/Scala

This certainly works, but it takes four commands.

Let’s see if we can’t do better.  Delete those folders with the command

rm -rf Programming/

This will delete the programming folder and all subfolders underneath it (the r flag is for recursive, the f flag for forcing the removal of nonempty directories)

Like most unix commands, the mkdir command can take multiple arguments, separated by spaces.  So the three separate commands to create Java, Python, and Scala can be put onto one line.

mkdir Programming; mkdir Programming/Java Programming/Python Programming/Scala

Note the ; separator between the two commands.  We need to create the Programming folder before we can create the subfolders.

This is better but still too verbose.  It would be nice to remove the mkdir Programming call; we’d like to be able to create an arbitrarily nested folder and have mkdir create all the parent folders automatically.  Fortunately there is a way to do this: the -p flag of mkdir does exactly this.

 -p      Create intermediate directories as required.  If this option is not specified, the full path prefix of
             each operand must already exist.  On the other hand, with this option specified, no error will be
             reported if a directory given as an operand already exists.  Intermediate directories are created with
             permission bits of rwxrwxrwx (0777) as modified by the current umask, plus write and search permission
             for the owner.

Thus we can change our command to

mkdir -p Programming/Java Programming/Python Programming/Scala

This is better but still not perfect; we’re repeating ourselves 3 times with the Programming call.  Enter an absurdly useful Bash shell construct known as brace expansion.

echo {5,6,7}
5 6 7

The arguments within braces are treated as if they were space separated instead.  That wouldn’t be terribly useful except that things immediately before the brace are repeated as well

echo hello{5,6,7}
hello5 hello6 hello7

This brace expansion can be used anywhere, since the textual substitution happens before the arguments are passed into other processes.  So, combining this with what we saw earlier, we can put Java, Python and Scala into a list and prepend it with Programming:

 echo Programming/{Java,Python,Scala}
Programming/Java Programming/Python Programming/Scala

That should look very familiar.  Putting it in place of the earlier mkdir command we get the elegant one liner

mkdir -p Programming/{Java,Python,Scala}

Certain versions of bash also support numerical ranges within the brackets:

echo {1..10}
1 2 3 4 5 6 7 8 9 10

Conclusion:

I have shown you how to create all the parent directories using the mkdir command, and introduced you to the brace expansion macro of Bash.  The latter is extremely powerful, and can be used to great effect within scripts.

Note: The arguments within the braces must have NO space between after or before the commas in order for the brace expansion to work.

[572][nicholasdunn: Desktop]$ echo {5, 6, 7}
{5, 6, 7}
[573][nicholasdunn: Desktop]$ echo {5,6,7}
5 6 7
Advertisement
Categories: programming Tags: , ,
  1. George
    April 11, 2010 at 9:21 pm

    Pretty cool!

  2. Andrew
    April 11, 2010 at 10:25 pm

    I really wish I’d know this a long while ago.

    • i82much
      April 12, 2010 at 8:45 am

      Yeah, once I found out about the brace expansion, a whole new world of possibilities opened up.

      The mkdir -p is pretty useful too, especially if you have to create a deeply nested folder structure. I didn’t mention it in the article but you can have more than one set of braces; {a,b,c}{d,e,f} yields ad ae af bd be bf cd ce cf

  3. AG
    May 24, 2010 at 10:43 am

    Thanks for the tip on brace expansion. I came here after seeing the term mentioned in the bash manpage with no further explanation! -ag

  4. April 24, 2013 at 10:37 am

    Thanks honey ;-!
    Was searching (via https://duckduckgo.com) for the commands to create a dir and change immediately into it.

  5. hanker
    December 10, 2013 at 4:58 am

    Add this one example it is very usefull;
    mkdir -p {2009..2013}/{1..12}

  6. May 3, 2015 at 3:21 am

    another one:
    mkdir -p archief/{client1,client2,client3}/{2015..2025}/{{jan,mar,may,july,aug,oct,dec}/{1..31},feb/{1.28},{apr,june,sept,nov}/{1..30}}

  7. May 3, 2015 at 3:23 am

    after creating the folder structure, a file (example.txt) will be created in each (day) subfolder
    touch archief/{client1,client2,client3}/{2015..2025}/{{jan,mar,may,july,aug,oct,dec}/{1..31},feb/{1.28},{apr,june,sept,nov}/{1..30}}/example.txt

  8. i82much
    May 3, 2015 at 11:09 am

    That’s really slick. I didn’t know you could do the nested braces.

  9. Peter
    October 1, 2022 at 11:06 pm

    Thanks for your explanation !

  1. May 21, 2012 at 7:05 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: