Я хочу скопировать измененные файлы из репозитория 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 -)
Пара быстрых мыслей:
редактировать
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 '{print $2}'
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 \;