6

Linux: Копирование и создание директории назначения, если она не существует

2

Я хочу команду (или, возможно, опцию для cp), которая создает целевой каталог, если он не существует.

Пример:

cp -? файл /путь/к/копии/файла/по/очень/глубокому/пути

Как это можно реализовать?

5 ответ(ов)

6

Команда mkdir -p "$d" && cp file "$d" выполняет две операции. Первое — это создание директории с помощью mkdir -p "$d", где -p позволяет создать промежуточные директории, если они не существуют. Второе — это копирование файла с именем file в созданную директорию $d.

Важно отметить, что опция -p для mkdir позволяет избежать ошибок, если директория уже существует, в то время как для команды cp такой опции нет. Если вы попытаетесь использовать cp file "$d", и директория $d по каким-то причинам не существует, команда завершится неудачно с сообщением об ошибке. Таким образом, в этом случае использование конструкций с && позволяет сначала убедиться в успешном создании директории, прежде чем копировать туда файл.

3

Если оба из следующих условий верны:

  1. Вы используете GNU версию команды cp (а не, например, версию для Mac), и
  2. Вы копируете из существующей структуры каталогов и просто хотите ее воссоздать,

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

--parents
     Формирует имя каждого файла назначения, добавляя к целевому
     каталогу слэш и указанное имя исходного файла. Последний аргумент,
     переданный `cp`, должен быть именем существующего каталога. Например, команда:

          cp --parents a/b/c existing_dir

     копирует файл `a/b/c` в `existing_dir/a/b/c`, создавая все
     отсутствующие промежуточные каталоги.

Пример использования:

/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
0

Функция оболочки, которая выполняет то, что вам нужно, называется bury_copy, потому что она создает каталог для файла, в который он будет помещен. Вот пример реализации:

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

Как это работает:

  1. mkdir -p dirname $2: Эта часть команды создает все необходимые каталоги для пути, указанного во втором аргументе. dirname извлекает имя каталога из полного пути файла.
  2. cp "$1" "$2": Затем происходит копирование файла, указанного в первом аргументе, в директорию, созданную на предыдущем шаге, под именем файла, указанным во втором аргументе.

Как использовать:

Вы можете использовать функцию следующим образом:

bury_copy /путь/к/исходному_файлу /путь/к/новой/директории/файл

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

0

Вот один из способов сделать это:

mkdir -p `dirname /path/to/copy/file/to/is/very/deep/there` \
   && cp -r file /path/to/copy/file/to/is/very/deep/there

Команда dirname возвращает родительский каталог для указанного пути назначения. Использование mkdir -p \dirname ...`` позволяет создать этот каталог, что гарантирует, что при выполнении команды cp -r базовый каталог будет существовать.

Преимущество данного метода по сравнению с опцией --parents заключается в том, что он работает в случаях, когда последний элемент в пути назначения — это имя файла.

Кроме того, этот способ будет работать и на OS X.

0

Это было сказано очень поздно, но, возможно, поможет новичку где-то. Если вам нужно АВТОМАТИЧЕСКИ создавать папки, rsync будет вашим лучшим другом.

rsync /путь/к/исходному_файлу /путь/к/целевой_директории/которая_не_существует/
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь