Как заставить команду cp создать необходимые папки для копирования файла в пункт назначения

При копировании файла с помощью cp в папку, которая может или не может существовать, как мне получить cp, чтобы создать папку, если это необходимо? Вот что я пробовал:

[[email protected] nutch-0.9]# cp -f urls-resume /nosuchdirectory/hi.txt
cp: cannot create regular file `/nosuchdirectory/hi.txt': No such file or directory

Ответ 1

Если выполняется одно из следующих условий:

  • Вы используете версию GNU cp (а не, например, версию Mac), и
  • Вы копируете какую-либо существующую структуру каталогов, и вам просто нужно ее воссоздать

то вы можете сделать это с помощью флага --parents cp. На информационной странице (можно просмотреть http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html#cp-invocation или с помощью info cp или man cp):

--parents
     Form the name of each destination file by appending to the target
     directory a slash and the specified name of the source file.  The
     last argument given to `cp' must be the name of an existing
     directory.  For example, the command:

          cp --parents a/b/c existing_dir

     copies the file `a/b/c' to `existing_dir/a/b/c', creating any
     missing intermediate directories.

Пример:

/tmp $ mkdir foo
/tmp $ mkdir foo/foo
/tmp $ touch foo/foo/foo.txt
/tmp $ mkdir bar
/tmp $ cp --parents foo/foo/foo.txt bar
/tmp $ ls bar/foo/foo
foo.txt

Ответ 2

Чтобы расширить христианский ответ, единственным надежным способом сделать это было бы объединение mkdir и cp:

mkdir -p /foo/bar && cp myfile "$_"

В стороне, когда вам нужно создать только один каталог в существующей иерархии, rsync может сделать это за одну операцию. Фактически я являюсь поклонником rsync как гораздо более универсальной замены cp:

rsync -a myfile /foo/bar/ # works if /foo exists but /foo/bar doesn't.  bar is created.

Ответ 3

Я не знал, что вы можете сделать это с помощью cp.

Вы можете сделать это с помощью mkdir..

mkdir -p /var/path/to/your/dir

ИЗМЕНИТЬ См. Lhunath answer для включения cp.

Ответ 4

Для тех, кто находится на Mac OSX, возможно, самый простой способ обойти это - использовать ditto (только на Mac, AFAIK, хотя). Он создаст структуру каталогов, которая отсутствует в месте назначения.

Например, я сделал это

ditto 6.3.2/6.3.2/macosx/bin/mybinary ~/work/binaries/macosx/6.3.2/

где ~/work не содержал каталог двоичных файлов, прежде чем я запустил команду.

Я думал, что rsync должен работать аналогично, но, похоже, он работает только для одного уровня недостающих каталогов. То есть

rsync 6.3.3/6.3.3/macosx/bin/mybinary ~/work/binaries/macosx/6.3.3/

работал, потому что ~/work/binaries/macosx существовал, но не ~/work/binaries/macosx/6.3.2/

Ответ 5

 mkdir -p `dirname /nosuchdirectory/hi.txt` && cp -r urls-resume /nosuchdirectory/hi.txt

Ответ 6

Можно также использовать команду find:

find ./ -depth -print | cpio -pvd newdirpathname

Ответ 7

Такого варианта нет. Что вы можете сделать, так это запустить mkdir -p перед копированием файла

Я сделал очень классный script, который вы можете использовать для копирования файлов в местах, которые не существуют

#!/bin/bash
if [ ! -d "$2" ]; then
    mkdir -p "$2"
fi
cp -R "$1" "$2"

Теперь просто сохраните его, дайте ему разрешения и запустите его, используя

./cp-improved SOURCE DEST

Я ставлю параметр -R, но это просто черновик, я знаю, что это может быть, и вы улучшите его разными способами. Надеюсь, это поможет вам.

Ответ 8

rsync - это работа!

#file:
rsync -aqz _vimrc ~/.vimrc

#directory:
rsync -aqz _vim/ ~/.vim

Ответ 9

cp -Rvn /source/path/* /destination/path/
cp: /destination/path/any.zip: No such file or directory

Он не будет создавать существующие пути в месте назначения, если в пути есть исходный файл внутри. Это не создает пустые каталоги.

Момент назад я видел xxxxxxxx: Нет такого файла или каталога, потому что у меня закончилось свободное пространство. без сообщения об ошибке.

с такой же точностью:

ditto -V /source/path/* /destination/path
ditto: /destination/path/any.zip: No space left on device

после освобождения пространства cp -Rvn /source/path/* /destination/path/ работает как ожидалось

Ответ 10

Удивительно, но я не вижу правильного ответа в этой теме, просто используйте:

cp -r /foo/bar/baz /tmp

Как обычно, достаточно простого совета RTFM, выше будет скопировать файл baz в /tmp и под подкаталогами foo/bar (они будут созданы, если они не существуют)

cp --help
-R, -r, --recursive          copy directories recursively