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

15

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

Прочитав man-страницу 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 -)
ZelluX
источник

Ответы:

12

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

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

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

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

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

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

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

CK.
источник
4

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/
Кайл Брандт
источник
Это очевидно, но это синхронизирует все, не только измененные файлы, верно?
СК.
упс, пропустил это
Кайл Брандт
2

Вот эта строка для справки:

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
Тим Абелл
источник
1

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

xargs -d \\n -l '{}' mkdir -p \`dirname '{}'\` && cp '{}' /tmp/xen/
wazoox
источник
1

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

Изменить: я имею в виду, у меня есть источник dir: /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 домашнее задание / 1 / 1.1 user @ remote: / home / user / projects /

zimon
источник
0

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

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

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

ср-р
Каролис Т.
источник
0
  • построить структуру каталогов /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 \;
    
ren8zhu
источник