Назад | Перейти на главную страницу

Как скопировать файл и создать каталог, если он не существует?

Я хочу скопировать измененные файлы из репозитория svn в другой каталог, сохранив при этом их структуру каталогов.

После прочтения справочной страницы awk и xargs я нашел способ изменить имена файлов следующим образом:

$ svn status -q | awk '{ print $2 }' | xargs -d \\n -I '{}' cp '{}' /tmp/xen/

Но проблема в том, что таким образом структуры каталогов не сохраняются, я хочу скопировать такие файлы:

./common/superp.c -> /tmp/xen/common/superp.c
./common/m2mgr.c -> /tmp/xen/common/m2mgr.c
./common/page_alloc.c -> /tmp/xen/common/page_alloc.c
./arch/x86/mm.c -> /tmp/xen/arch/x86/mm.c
./arch/x86/mm/shadow/private.h -> /tmp/xen/arch/x86/mm/shadow/private.h

Я попытался изменить команду cp на cp '{}' / tmp / xen / '{}' но он сказал, что нет такого файла или каталога. Есть ли способ сделать копию файла cp и создать каталог, если это необходимо? И, пожалуйста, укажите, можно ли упростить эту цепочку команд. :-)

Спасибо за все ваши ответы. Поскольку каталог немного велик, я не хочу копировать весь каталог с помощью cp -R или rsync. Предложение CK об использовании смоляной трубки весьма полезно.

svn status -q | awk '{ print $2 }' | xargs tar cf -  | (cd /tmp/xen/; tar xvf -)

Пара быстрых мыслей:

  • Добавьте mkdir -p $ (имя каталога FILE)
  • Не могли бы вы использовать трубку для дегтя, чтобы во всем разобраться?

редактировать

 tar -cf archive.tar  `svn status -q | awk '{print $2}'`

Следует создать архив измененных файлов. Затем:

  tar -xf archive.tar -C /tmp/xen

следует положить туда, куда вы хотите. Если это нужно сделать за один шаг, это тоже возможно.

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

rsync -av /home/source/svn/repo /home/dest/svn/

Это создаст каталог репо и все его содержимое в каталоге / home / dest / svn, поэтому у вас будет / home / dest / svn / repo / ...

Итак, для вас пример:

rsync -rv ./ /tmp/xen/

-a, сохранит отметки времени и будет, помимо прочего, рекурсивным, 'man rsync'.

Обновите, поняв, что я неправильно прочитал вопрос:

Чтобы имитировать структуру каталогов (альтернатива tar):

rsync -av --include='*/' --exclude='*' source destination

А затем скопировать файлы, скажем, 20 минут назад:

find . -type f -mmin -20 -print0 | xargs -0 cp --target-directory /mydestdir/

Вот этот однострочный текст для справки:

svn status -q | awk '{print $2}' | xargs tar -c | tar -xC /tmp/xen

И на английском:

  • получить список интересующих файлов с помощью svn status -q, который подключен к ...
  • awk, который извлекает столбец с путями к файлам: awk '{print $2}'
  • xargs используется для передачи списка файлов tar, который, в свою очередь, отправляет tarball файлов в stdout: xargs tar -c
  • который быстро извлекается повторно (-x) в целевой каталог (-C path): tar -xC /tmp/xen

Используйте "dirname", чтобы извлечь путь "mkdir -p" для его создания, например:

xargs -d \\n -l '{}' mkdir -p \`dirname '{}'\` && cp '{}' /tmp/xen/

rsync -a не создает новые каталоги глубже, чем на глубине 1, поэтому rsync является лишь частичным решением и, например, не подходит для меня (я искал в googledd ответ, как сделать каталоги rsync для некоторой удаленной иерархии, когда несколько каталогов отсутствуют посередине )

Изменить: я имею в виду, у меня есть исходный каталог: /home/user/projects/homework/1/1.1/ И я хочу rsync его на удаленный: /home/user/projects/homework/1/1.1/ ... но пункт назначения еще нет каталога / home / user / projects / homework ... и я не хочу переносить другие подкаталоги на исходном компьютере, которые находятся в / home / user / projects /

Edit2: нашел способ с параметром rsync --relative: приведенный выше пример будет выглядеть следующим образом:

cd / home / projects /; rsync -aR homework / 1 / 1.1 пользователь @ удаленный: / home / user / projects /

Я бы предложил следующее:

  • скопировать все
  • найти немодифицированные файлы и удалите их, оставив измененные файлы на своих местах.

Кстати, cp с флагом R копирует файлы / папки рекурсивно.

cp -R
  • построить структуру каталогов в /tmp/f2 для файлов в /tmp/f

    $ cd /tmp/f/
    $ find . -type f -exec dirname {} \; | uniq | xargs -I {} mkdir /tmp/f2/{} -p
    
  • скопировать файл в новое место назначения /tmp/f2/

    $ cd /tmp/f
    $ find . -type f -exec cp  {}  /tmp/f2/{} -aPv \;