69

Is there a flag/option for touch, mkdir, >, or some other command that will allow me to create a file and any non-existent parent directories at the same time?

For instance, let's say I'm in an empty folder. Now I can create parent directories if they don't exist when creating a folder

mkdir -p nested/folder

I can create files in existing directories

touch nested/folder/something.txt

But I can't create a file in a directory that doesn't exist yet

touch nested/folder/deep/more.txt

touch: cannot touch ‘nested/folder/deep/more.txt’: No such file or directory

How would I create that deep folder at the same time I create more.txt ?

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Jeff Puckett
  • 859
  • 1
  • 8
  • 12
  • Thanks! I came here because I was having a similar issue with `cat` and responses below proved helpful A little more info about `mkdir -p` http://www.linfo.org/make_directory_tree.html – frederj Aug 18 '20 at 21:34

1 Answers1

56

You can combine the two commands on a single line. If you use a variable you can do this:

file="./nested/folder/deep/more.txt"

And then this:

mkdir -p "${file%/*}" && touch "$file"

Or all together on one line like this:

mkdir -p "./nested/folder/deep" && touch "./nested/folder/deep/more.txt"

It's not one single command but it might do the job for you.

bashBedlam
  • 999
  • 6
  • 6
  • 17
    I recommend `dirname ${file}` instead of cryptic `${file%/*}` – Felix K. Aug 25 '18 at 21:51
  • 10
    The question got to something I've been wanting for a long time, but while this answer got me there, it didn't give me exactly what I wanted. So I wanted to share this function that I just created `mktouch() { mkdir -p $(dirname $1) && touch $1; }`. I put that in my `.bash_profile` and now I can do `mktouch dir/path/file.ext` and it creates the directory and touches in one command – Brian Underwood Nov 21 '18 at 08:19
  • 9
    @BrianUnderwood probably a good idea to wrap things in quotes: `mkdir -p "$(dirname "$1")" && touch "$1"` – mwfearnley Nov 27 '18 at 11:46
  • Fixed in in my `.bash_profile`, thanks! – Brian Underwood Nov 28 '18 at 12:07
  • @mwfearnley How to properly wrap commands in nested quotes in `"$(dirname "$1")"`. I tried your command but it created weird directories and didn't touch any files. Then I tried using single quote outside, and then tried single quote inside, and also tried backticks. Currently I have only wrapped $1 in quotes and kept dirname command itself without quotes. I should also disclose that i am using `$@` instead of `$1` to accept multiple parameters. – Abhinav Kulshreshtha Feb 14 '19 at 14:39
  • 5
    mkdir -p parent/child && touch $_/file.txt – francis Mar 19 '20 at 05:46
  • I hate when I see this... "How do I do X in one command?" "Oh, it's simple. Just do two commands and join them on one line". And it's like... no... they clearly want "One Command" – RoboticRenaissance May 18 '21 at 15:45
  • Actually, this answer contains 2 cmds put together in one line. I think this is not the answer the questioner wants! – AATHITH RAJENDRAN Jul 04 '22 at 12:45
  • `dirname` calls an external program, `${file%/*}` uses shell builtins, hence is more resource efficient. – Pound Hash Nov 25 '22 at 21:27