How to Make Mv Create the Directory to Be Moved to If It Doesn't Exist

Is there a way to make mv create the directory to be moved to if it doesn't exist?

How about this one-liner (in bash):

mkdir --parents ./some/path/; mv yourfile.txt $_

Breaking that down:

mkdir --parents ./some/path
# if it doesn't work; try
mkdir -p ./some/path

creates the directory (including all intermediate directories), after which:

mv yourfile.txt $_

moves the file to that directory ($_ expands to the last argument passed to the previous shell command, ie: the newly created directory).

I am not sure how far this will work in other shells, but it might give you some ideas about what to look for.

Here is an example using this technique:

$ > ls
$ > touch yourfile.txt
$ > ls
yourfile.txt
$ > mkdir --parents ./some/path/; mv yourfile.txt $_
$ > ls -F
some/
$ > ls some/path/
yourfile.txt

mv command creates directories

Either you're executing another mv binary, executing another version of mv, or something is wrapping it up like a function, a script or perhaps an alias.

To know if you're really running the real mv or not, run

type mv

You should get

mv is /bin/mv

As suggested by Etan Reisner, you can also add -a to have more information:

type -a mv

UPDATE

Directories /one/two/three/four exists also directories /one/two/five
exists. Executing mv /one/two/three/four/ /one/two/five/six will
succeed. Here directory six will get created even though it is not
present. This doesn't happen in the case when I execute mv
/one/two/three/four /one/two/five/six and the "five" directory doesn't
exists. In this case it will give error.

Since /one/two/five existed it simply moved your directory /one/two/three/four as /one/two/five/six. That means /one/two/five/six is now the new name or pathname of the directory which was previously /one/two/three/four.

How to mkdir only if a directory does not already exist?

Try mkdir -p:

mkdir -p foo

Note that this will also create any intermediate directories that don't exist; for instance,

mkdir -p foo/bar/baz

will create directories foo, foo/bar, and foo/bar/baz if they don't exist.

Some implementation like GNU mkdir include mkdir --parents as a more readable alias, but this is not specified in POSIX/Single Unix Specification and not available on many common platforms like macOS, various BSDs, and various commercial Unixes, so it should be avoided.

If you want an error when parent directories don't exist, and want to create the directory if it doesn't exist, then you can test for the existence of the directory first:

[ -d foo ] || mkdir foo

Create directory when it does not exist

You can check using file_exists, which is the best approach, but it's also helpful to know how to handle exceptions.

Please note mkdir requires a permissions value. I'll use 777 for the sake of full permissions, but in practice this is probably a bad idea.

try 
if not (Sys.is_directory "vegetables") then
Sys.mkdir "vegetabels" 777
with Sys_error _ ->
Sys.mkdir "vegetabels" 777

Alternatively, Sys.mkdir raises an exception if the directory or file already exists, so we can try to create the directory, and handle that exception by doing nothing.

try
Sys.mkdir "vegetabels" 777
with Sys_error _ -> ()

Note: when you use exception handling, it's not an excuse to forget about type-checking. The type of the body of your try needs to have the same type as any with clauses. Since Sys.mkdir returns unit if successful, the exception handling clause needs to do the same.

Linux: copy and create destination dir if it does not exist


mkdir -p "$d" && cp file "$d"

(there's no such option for cp).

Windows Batch move to directory that may not exist

Try:

md c:\aaa\111\222\333\444 2> nul

before your Move command.

md makes directories recursive, so if there are no parent directories to 444, it will keep creating hierarchically. The "2> nul" ensures that if you have the directory already, your command wouldnt error out.

Shell Script - Make directory if it doesn't exist


if [ -L $dirname]

Look at the error message produced by this line: “[: missing `]'” or some such (depending on which shell you're using). You need a space inside the brackets. You also need double quotes around the variable expansion unless you use double brackets; you can either learn the rules, or use a simple rule: always use double quotes around variable substitution and command substitution"$foo", "$(foo)".

if [ -L "$dirname" ]

Then there's a logic error: you're creating the directory only if there is a symbolic link which does not point to a directory. You presumably meant to have a negation in there.

Don't forget that the directory might be created while your script is running, so it's possible that your check will show that the directory doesn't exist but the directory will exist when you try to create it. Never do “check then do”, always do “do and catch failure”.

The right way to create a directory if it doesn't exist is

mkdir -p -- "$dirname"

(The double quotes in case $dirname contains whitespace or globbing characters, the -- in case it starts with -.)

is there a touch that can create parent directories like mkdir -p?

There is no touch that can create parent directory path, so write your own in standard POSIX-shell grammar that also works with zsh:

#!/usr/bin/env sh

touchp() {
for arg
do
# Get base directory
baseDir=${arg%/*}

# If whole path is not equal to the baseDire (sole element)
# AND baseDir is not a directory (or does not exist)
if ! { [ "$arg" = "$baseDir" ] || [ -d "$baseDir" ];}; then
# Creates leading directories
mkdir -p "${arg%/*}"
fi

# Touch file in-place without cd into dir
touch "$arg"
done
}


Related Topics



Leave a reply



Submit