Create file and its parent directory
touch
is not able to create directories, you need mkdir
for that.
However, mkdir
has the useful -p
/--parents
option which creates a full directory structure.
From man mkdir
:
-p, --parents
no error if existing, make parent directories as needed
So the command you need in your specific situation is:
mkdir -p ~/Desktop/a/b/c/d/e/f/g/h/ && touch ~/Desktop/a/b/c/d/e/f/g/h/1.txt
If you think you will need this more often and don't want to type the path twice every time, you can also make a Bash function or a script for it.
-
Bash function (append this line to
~/.bashrc
to persitently have it available to your user, otherwise it will vanish again when you exit your terminal):touch2() { mkdir -p "$(dirname "$1")" && touch "$1" ; }
It can be simply used like this:
touch2 ~/Desktop/a/b/c/d/e/f/g/h/1.txt
-
Bash script (store it in
/usr/local/bin/touch2
using sudo to make it available for all users, else in~/bin/touch2
for your user only):#!/bin/bash mkdir -p "$(dirname "$1")" && touch "$1"
Don't forget to make the script executable using
chmod +x /PATH/TO/touch2
.After that you can also run it like this:
touch2 ~/Desktop/a/b/c/d/e/f/g/h/1.txt
One can use install
command with -D
flag.
bash-4.3$ install -D /dev/null mydir/one/two
bash-4.3$ tree mydir
mydir
└── one
└── two
1 directory, 1 file
bash-4.3$
If we have multiple files, we might want to consider using a list of items(note, remember to quote items with spaces), and iterating over them:
bash-4.3$ for i in mydir/{'subdir one'/{file1,file2},'subdir 2'/{file3,file4}} ; do
> install -D /dev/null "$i"
> done
bash-4.3$ tree mydir
mydir
├── one
│ └── two
├── subdir 2
│ ├── file3
│ └── file4
└── subdir one
├── file1
└── file2
Or alternatively with array:
bash-4.3$ arr=( mydir/{'subdir one'/{file1,file2},'subdir 2'/{file3,file4}} )
bash-4.3$ for i in "${arr[@]}"; do install -D /dev/null "$i"; done
bash-4.3$ tree mydir
mydir
├── one
│ └── two
├── subdir 2
│ ├── file3
│ └── file4
└── subdir one
├── file1
└── file2
mkdir -p parent/child && touch $_/file.txt