Как я могу скопировать файл и создать целевые каталоги одновременно?

20

Я хочу cp aaa/deep/sea/blob.psdчтобыbbb/deep/sea/blob.psd

Как сделать копию , если deepи seaкаталоги не существуют под bbbтаким образом , что копия и создает каталоги, которые необходимы и копирует файл?

Прямо сейчас я
No such file or directoryтак глубоко и моря не существует.

Я просмотрел справочные страницы человека и другие вопросы, но ничего не выскакивает на меня.

Самое близкое, что у меня есть, это использование rcpдля каталога:

rcp -r aaa/deep/sea/ bbb/deep/sea/

хотя это копирует весь каталог и содержимое, и я просто хочу один файл. Попытка сделать это однако далаcp: cannot create regular file bbb/deep/sea/blob.psd' such file or directory

Майкл Даррант
источник

Ответы:

19

Попробуйте использовать такую ​​следующую функцию для такой ситуации:

copy_wdir() { mkdir -p -- "$(dirname -- "$2")" && cp -- "$1" "$2" ; }

и использовать его как

copy_wdir aaa/deep/sea/blob.psd bbb/deep/sea/blob.psd

Кстати, у GNU cpесть --parentsопция. Это действительно близко к тому, что вы хотите, но не совсем так.
Он также создаст aaaкаталог, который вам не нужен. Однако сначала вы можете aaaскопировать и скопировать:

cd aaa && cp --parents deep/sea/blob.psd ../bbb/
порыв
источник
24

Легко использовать installпрограмму из coreutils, которая обычно используется для этой цели сборочными системами, такими как automake :

install -D /path/to/source /path/to/destination

Обратите внимание, что installсоздает все части пути так же, как mkdir -pделает, см man install. Мне любопытно, почему вы не указали, почему вы хотите это сделать. Звонит mkdirи cpочень легко.

Павел Шимерда
источник
2
Я думаю, что есть много хороших ответов на этот вопрос, но этот получает мой голос, так как он самый переносимый. rsyncОтвет будет только создать 1 каталог, и , paxкажется, не является общим.
Патрик
Используйте -dвместо -DMac.
Мэтт М.
обратите внимание, что эта команда создает файлы назначения с разрешениями 755( rwxr-xr-x), что, вероятно, нежелательно. Вы можете указать что-то еще с помощью -mпереключателя, но я не смог найти способ просто сохранить права доступа к файлу :(
törzsmókus
6

Со стандартными (POSIX / Unix) командами вы получаете:

pax -rws ':^:dest/dir/:' file .
Стефан Шазелас
источник
1
Интересный. Я никогда не слышал о Пакс раньше. Хотя мне нравится его концепция. К сожалению, несмотря на то, что он в POSIX, кажется, очень мало дистрибутивов устанавливают его по умолчанию :-(
Патрик
@ Патрик - если вы пропустите весь путь до конца info tar- где-то в разделе, посвященном вопросам переносимости, - я думаю, вы обнаружите, что GNU tarзаявляет, что он полностью paxсовместим. В любом случае, хотя я так и не удосужился проверить эти претензии.
mikeserv
5

Я не знаю способ сделать это с помощью cp, но это, безусловно, возможно с помощью rsync:

$ rsync sourcefile dir/

где dirкаталог, который не должен существовать. Есть много других способов добиться того же, используя другие команды.

mjturner
источник
3
Вам нужно rsync -Rсохранить каталог heirarchy
Гленн Джекман
@glennjackman Действительно, для «правильного» использования rsyncтребуется больше опций, но вопрос был просто о создании несуществующего целевого каталога, отсюда мой краткий ответ :)
mjturner
1
По крайней мере, GNU cpимеет --parentsвозможность.
Петерф
2
@peterph Действительно, но тогда вы ограничены в именовании целевого каталога
mjturner
4
cd aaa
pax -rw deep/sea/blob.psd ../bbb

Если у вас нет pax (это предписано POSIX, как стандартная замена cpio и tar, у которых было слишком много несовместимостей для стандартизации), используйте cpio -pили tar -cf - … | tar -xf -вместо этого.

Жиль "ТАК - перестать быть злым
источник