Unix - create path of folders and file
LinuxBashShellUnixScriptingLinux Problem Overview
I know you can do mkdir
to create a directory and touch
to create a file, but is there no way to do both operations in one go?
i.e. if I want to do the below when the folder other
does not exist:
cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
Error:
cp: cannot create regular file `/my/other/path/here/cpedthing.txt': No such file or directory
Has anyone come up with a function as a workaround for this?
Linux Solutions
Solution 1 - Linux
Use &&
to combine two commands in one shell line:
COMMAND1 && COMMAND2
mkdir -p /my/other/path/here/ && touch /my/other/path/here/cpedthing.txt
Note: Previously I recommended usage of ;
to separate the two commands but as pointed out by @trysis it's probably better to use &&
in most situations because in case COMMAND1
fails COMMAND2
won't be executed either. (Otherwise this might lead to issues you might not have been expecting.)
Solution 2 - Linux
You need to make all of the parent directories first.
FILE=./base/data/sounds/effects/camera_click.ogg
mkdir -p "$(dirname "$FILE")" && touch "$FILE"
If you want to get creative, you can make a function:
mktouch() {
if [ $# -lt 1 ]; then
echo "Missing argument";
return 1;
fi
for f in "$@"; do
mkdir -p -- "$(dirname -- "$f")"
touch -- "$f"
done
}
And then use it like any other command:
mktouch ./base/data/sounds/effects/camera_click.ogg ./some/other/file
Solution 3 - Linux
Do it with /usr/bin/install:
install -D /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
when you don't have a source file:
install -D <(echo 1) /my/other/path/here/cpedthing.txt
Solution 4 - Linux
This is what I would do:
mkdir -p /my/other/path/here && touch $_/cpredthing.txt
Here, the $_
is a variable that represents the last argument to the previous command that we executed in line.
As always if you want to see what the output might be, you can test it by using the echo
command, like so:
echo mkdir -p /code/temp/other/path/here && echo touch $_/cpredthing.txt
Which outputs as:
mkdir -p /code/temp/other/path/here
touch /code/temp/other/path/here/cpredthing.txt
As a bonus, you could write multiple files at once using brace expansion, for example:
mkdir -p /code/temp/other/path/here &&
touch $_/{cpredthing.txt,anotherfile,somescript.sh}
Again, totally testable with echo
:
mkdir -p /code/temp/other/path/here
touch /code/temp/other/path/here/cpredthing.txt /code/temp/other/path/here/anotherfile /code/temp/other/path/here/somescript.sh
Solution 5 - Linux
#!/bin/sh
for f in "$@"; do mkdir -p "$(dirname "$f")"; done
touch "$@"
Solution 6 - Linux
you can do it in two steps:
mkdir -p /my/other/path/here/
touch /my/other/path/here/cpedthing.txt
Solution 7 - Linux
if [ ! -d /my/other ]
then
mkdir /my/other/path/here
cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
fi
Solution 8 - Linux
as I saw and test in a unix forum this solves the problem
ptouch() {
for p in "$@"; do
_dir="$(dirname -- "$p")"
[ -d "$_dir" ] || mkdir -p -- "$_dir"
touch -- "$p"
done
}
Solution 9 - Linux
no need for if then
statements...
you can do it on a single line usign ;
mkdir -p /my/other/path/here;cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
-- or on two lines --
mkdir -p /my/other/path/here
cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
-- the -p
prevents error returns if the directory already exists (which is what I came here looking for :))
Solution 10 - Linux
In the special (but not uncommon) case where you are trying to recreate the same directory hierarchy, cp --parents
can be useful.
For example if /my/long
contains the source files, and my/other
already exists, you can do this:
cd /my/long
cp --parents path/here/thing.txt /my/other
Solution 11 - Linux
if you want simple with only 1 param snippet :
rm -rf /abs/path/to/file; #prevent cases when old file was a folder
mkdir -p /abs/path/to/file; #make it fist as a dir
rm -rf /abs/path/to/file; #remove the leaf of the dir preserving parents
touch /abs/path/to/file; #create the actual file