Unix - create path of folders and file
Solution 1
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
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
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
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
#!/bin/sh
for f in "$@"; do mkdir -p "$(dirname "$f")"; done
touch "$@"
toop
Updated on August 20, 2020Comments
-
toop over 3 years
I know you can do
mkdir
to create a directory andtouch
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?
-
Seng Cheong over 10 yearsChanged it to use
&&
- How's that? -
BЈовић over 10 yearsIs bash supporting return in functions?
-
Seng Cheong over 10 years@BЈовић Yes. (I do try to test things before I post them.)
-
devnull over 10 years@JonathonReinhart Are you sure that you tested it? I tried
supertouch "/tmp/abc/def ghi/jkl mno.txt"
and it failed. All the commandsdirname
,mkdir
, andtouch
gave erros. -
Seng Cheong over 10 years@devnull Apparently not well enough. Damn your spaces :-) Fixed.
-
devnull over 10 years@JonathonReinhart Good to see that you've quoted the arguments.
-
trysis almost 9 yearsProbably better to use
&&
, as with;
, if the first command fails, the second command will still run (and fail, too, as that directory does not exist yet). With&&
if the first command fails, the second command does not run. -
Jeremy Iglehart about 8 years@JonathonReinhart I like the script very much, but suggest the name "mktouch" - added to my .profile - Thanks!
-
Seng Cheong about 8 years@JeremyIglehart I like it.
mktouch
it is. -
Sgnl about 8 yearsA short cut for the code example can be:
mkdir -p /my/other/path/here && touch $_/cpredthing.txt
. The$_
expands to essentially the "last argument in the last command executed". -
leftaroundabout about 8 yearsIf you want to simply get rid of the last few hours'† work, gratitiously throw around some
rm -rf
commands. — †That is, hours, assuming you adhere to a sensible version control / backup policy... otherwise, it might well be months. -
SC-SL over 7 yearsI am surprised this gem tool is largely ignored - man install - will show that install is a better solution.
-
Choylton B. Higginbottom over 6 years@Sgnl yours is arguably the correct answer. It is not just cleaner, it is less error-prone.
-
jpaugh over 6 yearsAn anonymous user suggested (via edit) to use
dirname -z "$@" | xargs -0 mkdir -p
instead, for performance's sake. (Stop lurking, and join, for Pete's sake! ;-) -
wisbucky almost 6 yearsYou can also use
-D /dev/null
, which is easier for me to remember. -
Mausy5043 over 5 years
rm -rf
should never be suggested without proper explanation and warnings. -
Ben174 about 5 yearsI really wish
touch
took a-p
parameter likemkdir
does.