Скопируйте все файлы и папки, кроме файлов и папок Subversion в OS X


14

Я пытаюсь скопировать все файлы и папки из одного каталога в другой, но исключаю определенные файлы. В частности, я хочу исключить файлы и папки Subversion. Тем не менее, я хотел бы общее, но краткое решение.

Я предполагаю, что найду необходимость исключить несколько типов файлов в ближайшем будущем. Например, я могу захотеть исключить .svn, * .bak и * .prj.

Вот то, что я собрал так для, но это не работает для меня. Первая часть, найди работы, но я делаю что-то не так с xargs и cp . Я попробовал cp с и без -R. Кроме того, я использую OS X, и у нее, похоже, менее функциональная версия xargs, чем в системах Linux.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory

Я могу ошибаться, но я думаю, что это сложнее, чем вы думаете. Даже если ваша findкоманда правильно использует -pruneисключение элементов .svn, вы передаете -Rфлаг, cpкоторому эта команда сообщает рекурсивную. Когда это происходит, вы теряете все детали, которые были у вас в findкоманде. Я собираюсь повозиться с этим на минуту, но я думаю, что ответ не использовать -Rв cpкоманде.
Телемах

Кажется, у меня работает в системе Linux. Можете ли вы быть более конкретным относительно того, что означает "это не работает"? Есть сообщения об ошибках? Файлы получают / не копируются, что вы ожидаете?
Приостановлено до дальнейшего уведомления.

Это -Rфлаг, я уверен. Удалите это, и у вас все будет хорошо (хотя вы можете добавить, -mindepth 1чтобы игнорировать папку каталога верхнего уровня, которую вы не хотите копировать, я полагаю)
Telemachus

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

Ответы:


22

(Отредактировано после перечитывания вопроса. Спрашивающий говорит, что rsync не установлен)

Возможная проблема с вашим решением find / xargs - пробелы в именах файлов. Чтобы обойти это, скажите find и xargs использовать нулевой символ (ASCII 0) для разделения найденных файлов:

find ./sourcedirectory -not ( -name .svn -a -prune ) -print0 | xargs -0 -IFILES cp FILES ./destinationdirectory

Если вы обнаружите, что rsync доступен, я все же думаю, что rsync - гораздо лучшее решение:

Используйте rsync с опцией -C. Со страницы руководства rsync :

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

Это скажет rsync игнорировать эти шаблоны:

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~
#* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj 
*.so *.exe *.Z *.elc *.ln core .svn/ .git/ .bzr/

Например:

rsync -avC /path/to/source/directory /path/to/destination/directory

(примечание: если вы еще не слишком знакомы с rsync, обязательно прочитайте на этой странице руководства о том, как rsync справляется с завершающей косой чертой в исходном пути. Если вы включите косую черту, она будет вести себя иначе, чем если бы вы этого не делали. Поиск "косая черта")


Ох, крысы, я просто перечитал ваш вопрос и увидел, что вы сказали, что у вас не установлен rsync. На моем MacBook Pro (OS X 10.6.1) он находится в / usr / bin / rsync. Он был установлен для меня под Tiger (10.4) и Leopard (10.5).
Даг Харрис

Я почти уверен, что вы (и ОП) не хотите -Rфлаг в xargsчасти команды.
Телемах

Хороший улов, я скопировал это из оригинального вопроса. Буду редактировать сейчас.
Даг Харрис

1
Спасибо, Даг! Одна вещь, которую я проповедую, «используйте правильный инструмент для работы». Я недавно пришел из мира Windows в OSX и до сих пор ворочаюсь в невежестве. Я разместил этот же вопрос на канале linux, и кто-то быстро сказал: просто используйте «rsynch», я набрал «rsynch» в терминале и увидел, что его не существует, и продолжил расследование находки | XARGS подход. Я немного такой упрямый. В любом случае, в OSX по умолчанию есть «rsync», и ваш пост был очень полезным. У меня пока нет достаточного опыта, чтобы знать, что лучше, но rsync уверен, что он гораздо лаконичнее. Благодарность!
Майкл Прескотт

Если вы будете выполнять какую-либо работу с Linux-машинами в дополнение к своей работе в OS X, я думаю, вы найдете, что стоит потратить время на то, чтобы научиться использовать rsync. Его основная функция - интеллектуальное копирование только измененного материала (например, робокопия в Windows, если вы знакомы с этим). Поскольку он копирует только дельту, это отличный способ обрабатывать резервные копии (не связанные с Time Machine), развертывания кода и тому подобное.
Даг Харрис

2

Не общие решения, но ... вы можете использовать команду svn export для создания копии рабочей области без папок метаданных .svn.


Не обижаться, но я не уверен, почему за этот ответ проголосовали. Я знаю о возможностях svn, но «я хотел бы получить общее, но лаконичное решение. Думаю, я найду необходимость исключить несколько типов файлов в ближайшем будущем»
Майкл Прескотт,

2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

если вы хотите, вы можете даже поместить 'pv' или что-то подобное между процессами 2 tar.


2

Грязный, но быстрый и лаконичный способ:

cp -r source destination
find destination -iname .svn |xargs rm -rf

Это копирует один каталог в другой (таким образом, рекурсивный вариант -r), а затем рекурсивно стирает все с именем .svn(игнорируя регистр).


1

Я бы пошел по-другому, используя tar и механизм исключения.

От в каталоге назначения:

tar -X excludefile -C source -f - . | tar xf -

Это перейдет к исходному тексту, сохранит содержимое, исключая то, что указано в excludefile, и затем распакует его в текущий каталог.


Действительно элегантное решение.
Ник Stinemates

ну, это тот же ответ, который я дал, только позже. Кроме того, вы должны быть в каталоге назначения ... :)
Акира

0

Отредактированный ответ : проблема в том, что -Rкопирование становится рекурсивным, и в итоге вы копируете скрытые файлы. Вот что я бы использовал:

find source/  -mindepth 1 -not \( -name .svn -prune \) | xargs -Iitem cp item target/

-mindepth 1Флаг указывает findигнорировать каталог верхнего уровня. Поскольку вы хотите скопировать все содержимое этого каталога в новый каталог верхнего уровня, я предполагаю, что вы этого не хотите.

Как говорит Крис Нава в своем ответе , уже есть встроенный способ сделать это, если мы говорим о папках SVN, но, поскольку вы попросили более общее решение, это может немного помочь.


Спасибо Телемаху, это полезно. У меня нет опыта критиковать, но я повторю то, что мне сказали со времени моего первоначального поста. «xargs не работает» Неизвестный комментатор irc, который сказал мне, вдохновил меня осмотреться побольше, и я думаю, что ответ Дуга Харриса решает проблему. Это говорит Xargs использовать нулевые символы. Я думаю, что это переключатель -0?
Майкл Прескотт

@Michael: xargsне сломан, но в Unix-подобных системах по умолчанию не используются имена файлов (или имена каталогов) с пробелами в них. Если у вас есть пробелы или «забавные» символы в именах файлов (или именах каталогов), вам придется проделать дополнительную работу, чтобы справиться с этим. (В GNU find, есть целый раздел в manстранице под названием «НЕОБЫЧНОЕ FILENAMES» из - за этот вопрос) . В -0флаге xargsи -print0для findпомощи справиться с этими проблемами. Я обещаю вам, однако, что вы не хотите использовать -Rв своей команде копирования. Он отменит все, что вы делаете, чтобы избежать каталогов SVN.
Телемах

0

Я полагаю, это зависит от того, насколько велико ваше дерево, но почему бы просто не скопировать все сначала, а затем обрезать папки .svn после:

find /dest-dir -type d -name .svn -exec rm -rf {} \;

?


Без какого-либо бенчмаркинга я изначально думал, что это двойная трата циклов ЦП: копирование и удаление. Правильное findкомандование может занять немного больше человеческого времени , но вы делаете это только один раз. Вы можете использовать команду сотни раз, как только вы ее правильно поняли.
Телемах

@Telemachus - правда, но это то, что компьютеры (должны быть) хороши - делать сложные вещи, поэтому нам не нужно! В самом деле - какой вред имеет копирование некоторых файлов только после того, как они вскоре будут удалены, если это означает, что команды, которые вы изобрели для этого, очень просты?
Стив Фолли,

@ Стив: нет никакого вреда, правда. Насколько это возможно, это прекрасное решение. Он следует одному принципу, который мне нравится: «Делай самую простую вещь, которая работает». С другой стороны, это нарушает еще один принцип, который мне нравится еще больше: «Изучите свои инструменты». Я бы предпочел научиться использовать findсебя лучше, чтобы мне не пришлось это делать. Но вы правы: в этом решении нет ничего плохого.
Телемах

@Telemachus: я согласен с "Изучите свои инструменты". Когда я начинал, я уверен, что моя команда поиска выше выглядела бы очень загадочно для меня тогда :-)
Стив Фолли,


0

Вы также можете сделать наоборот. Скопируйте все, затем удалите папки .svn, используя следующую команду:

find . | grep ".svn" | xargs rm -rf
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.