I want a command (or probably an option to cp) that creates the destination directory if it does not exist.
Example:
cp -? file /path/to/copy/file/to/is/very/deep/there
I want a command (or probably an option to cp) that creates the destination directory if it does not exist.
Example:
cp -? file /path/to/copy/file/to/is/very/deep/there
with all my respect for answers above, I prefer to use rsync as follow:
$ rsync -a directory_name /path_where_to_inject_your_directory/
example:
$ rsync -a test /usr/local/lib/
Just to resume and give a complete working solution, in one line. Be careful if you want to rename your file, you should include a way to provide a clean dir path to mkdir. $fdst can be file or dir. Next code should work in any case.
fsrc=/tmp/myfile.unk
fdst=/tmp/dir1/dir2/dir3/myfile.txt
mkdir -p $(dirname ${fdst}) && cp -p ${fsrc} ${fdst}
or bash specific
fsrc=/tmp/myfile.unk
fdst=/tmp/dir1/dir2/dir3/myfile.txt
mkdir -p ${fdst%/*} && cp -p ${fsrc} ${fdst}
As suggested above by help_asap and spongeman you can use the 'install' command to copy files to existing directories or create create new destination directories if they don't already exist.
Option 1
install -D filename some/deep/directory/filename
copies file to a new or existing directory and gives filename default 755 permissions
Option 2
install -D filename -m640 some/deep/directory/filename
as per Option 1 but gives filename 640 permissions.
Option 3
install -D filename -m640 -t some/deep/directory/
as per Option 2 but targets filename into target directory so filename does not need to be written in both source and target.
Option 4
install -D filena* -m640 -t some/deep/directory/
as per Option 3 but uses a wildcard for multiple files.
It works nicely in Ubuntu and combines two steps (directory creation then file copy) into one single step.
This is very late but it may help a rookie somewhere. If you need to AUTO create folders rsync should be your best friend.
rsync /path/to/sourcefile /path/to/tragetdir/thatdoestexist/
i strongly suggest ditto.
just works.
ditto my/location/poop.txt this/doesnt/exist/yet/poop.txt
Simply without creating script and with simple command ...
mkdir -p /destination-folder/ && cp file-name /destination-folder/
Just had the same issue. My approach was to just tar the files into an archive like so:
tar cf your_archive.tar file1 /path/to/file2 path/to/even/deeper/file3
tar automatically stores the files in the appropriate structure within the archive. If you run
tar xf your_archive.tar
the files are extracted into the desired directory structure.
Copy from source to an non existing path
mkdir –p /destination && cp –r /source/ $_
NOTE: this command copies all the files
cp –r for copying all folders and its content
$_ work as destination which is created in last command
Oneliner to create a small script that can be used as subcommand, in find for instance:
set +H; echo -e "#!/bin/sh\nmkdir -p \$(dirname \"\$2\"); cp \"\$1\" \"$2\"\;" > ~/local/bin/cpmkdir; chmod +x ~/local/bin/cpmkdir
You can then use it like:
find -name files_you_re_lookin_for.* -exec cpmkdir {} ../extracted_copy/{} \;
You can use find with Perl. Command will be like this:
find file | perl -lne '$t = "/path/to/copy/file/to/is/very/deep/there/"; /^(.+)\/.+$/; `mkdir -p $t$1` unless(-d "$t$1"); `cp $_ $t$_` unless(-f "$t$_");'
This command will create directory $t if it doesn't exist. And than copy file into $t only unless file exists inside $t.
This works on GNU /bin/bash version 3.2 on MacOS (tested on both Catalina and Big Sur)
cp -Rv <existing-source-folder>/ <non-existing-2becreated-destination-folder>
the "v" option is for verbose.
And I think of the "-R" option as "Recursive".
man's full description of -R is:
If source_file designates a directory, cp copies the directory and the entire subtree connected at that point. If the source_file ends in a /, the contents of the directory are copied rather than the directory itself. This option also causes symbolic links to be copied, rather than indirected through, and for cp to create special files rather than copying them as normal files. Created directories have the same mode as the corresponding source directory, unmodified by the process' umask.
In -R mode, cp will continue copying even if errors are detected.
Note that cp copies hard-linked files as separate files. If you need to preserve hard links, consider using tar(1), cpio(1), or pax(1) instead.
In the example below, I'm using a "/" at the end of existingfolder so that it copies all the contents of existingfolder (and not the folder itself) into newfolder:
cp -Rv existingfolder/ newfolder
Try it.
Only for macOS
rsync -R <source file path> destination_folder
For macOS --parents option of cp doesn't work
Many of the other solutions don't work on files or folders which need escaping. Here is a solution which works for files and folders, and escapes spaces and other special characters. Tested in a busybox ash shell which doesn't have access to some of the fancier options.
export file="annoying folder/bar.txt"
export new_parent="/tmp/"
# Creates /tmp/annoying folder/
mkdir -p "$(dirname "$new_folder/$file")"
# Copies file to /tmp/annoying folder/bar.txt
cp -r "$file" "$new_folder/$file"
This should also work if you omit bar.txt if you need the recursive copy of a whole folder.