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

24476
Michael Prescott

Я пытаюсь скопировать все файлы и папки из одного каталога в другой, но исключаю определенные файлы. В частности, я хочу исключить файлы и папки 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 
14
Я могу ошибаться, но я думаю, что это сложнее, чем вы думаете. Даже если ваша команда `find` правильно использует` -prune` для исключения элементов .svn, вы затем передаете флаг `-R` в` cp`, который сообщает * этой * команде, что она рекурсивная. Когда это происходит, вы теряете все детали, которые были у вас в команде `find`. Я собираюсь повозиться с этим на минуту, но я думаю, что ответом будет * не * использование `-R` в команде` cp`. Telemachus 15 лет назад 0
Кажется, у меня работает в системе Linux. Можете ли вы быть более конкретным относительно того, что означает "это не работает"? Есть сообщения об ошибках? Файлы получают / не копируются, что вы ожидаете? Dennis Williamson 15 лет назад 0
Я уверен, это флаг `-R` Удалите это, и все будет в порядке (хотя вы можете добавить `-mindepth 1`, чтобы игнорировать папку верхнего уровня, которую вы не хотите копировать, я полагаю) Telemachus 15 лет назад 0
Я обычно делаю эти вещи, копируя все, а затем удаляя ненужные файлы в целевых каталогах. Это часто намного проще. Jan Doggen 10 лет назад 0

9 ответов на вопрос

22
Doug Harris

(Отредактировано после повторного прочтения вопроса. Спрашивающий говорит, что 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). Doug Harris 15 лет назад 0
Я уверен, что вы (и ОП) не хотите флаг `-R` в части команды` xargs`. Telemachus 15 лет назад 0
Хороший улов, я скопировал это из оригинального вопроса. Буду редактировать сейчас. Doug Harris 15 лет назад 0
Thanks Doug! One thing I preach, "use the right tool for the job". I've recently come from Windows world to OSX and am still fumbling around in ignorance. I posted this same question in a linux channel and someone quickly said, just use "rsynch" I typed "rsynch" in the terminal and saw it didn't exist and continued investigating the find | xargs approach. I'm a bit stubborn like that. Anyhow, OSX does have "rsync" by default, and your post was very helpful. I don't have enough experience here yet to know which is better, but rsync sure is much more concise. Thanks! Michael Prescott 15 лет назад 1
Если вы будете выполнять какую-либо работу с Linux-машинами в дополнение к своей работе в OS X, я думаю, вам стоит потратить время на то, чтобы научиться использовать rsync. Его основной функциональностью является интеллектуальное копирование только измененного материала (например, робокопия в Windows, если вы знакомы с этим). Поскольку он копирует только дельту, это отличный способ обрабатывать резервные копии (не связанные с Time Machine), развертывания кода и тому подобное. Doug Harris 15 лет назад 0
-C flag решил так много проблем, которые у меня были ... ничего похожего на чтение всей страницы руководства. Спасибо gcb 13 лет назад 0
2
Chris Nava

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

Not to be offensive, but I'm not sure why this answer is getting up-voted. I'm aware of svn's capabilities, but "I'd like a general yet concise solution. I imagine I'll find the need to exclude several types of files in the near future" Michael Prescott 15 лет назад 0
2
akira
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn | tar xvf - -C FOLDER_OUT ) 

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

1
KeithB

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

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

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

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

Действительно элегантное решение. Nick Stinemates 15 лет назад 0
ну, это тот же ответ, который я дал, только позже. плюс вы должны быть в каталоге назначения ... :) akira 15 лет назад 0
1
michele

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

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

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

0
Telemachus

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

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

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

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

Thanks Telemachus, it is helpful. I don't have the experience to critique, but I'll repeat what I've been told since my original post. "xargs is broken" The unknown irc commenter that told me that inspired me to look around a bit more and I think Doug Harris's answer addresses the problem. That tell xargs to use null characters. I think that is the -0 switch? Michael Prescott 15 лет назад 0
@Michael: `xargs` не сломан, но в Unix-подобных системах по умолчанию не используются имена файлов (или имена каталогов) с пробелами в них. Если в ваших именах файлов (или именах каталогов) есть пробелы или «забавные» символы, вам придется проделать дополнительную работу, чтобы справиться с этим. (В GNU `find` есть целая секция на странице` man`, которая называется "UNUSUAL FILENAMES" из-за этой проблемы.) Флаг `-0` в` xargs` и `-print0` для` find` помогают справиться с этими проблемами. Однако я обещаю вам, что вы не хотите использовать `-R` в своей команде копирования. Он отменит все, что вы делаете, чтобы избежать каталогов SVN. Telemachus 15 лет назад 0
0
Steve Folly

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

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

?

Без какого-либо бенчмаркинга я изначально думал, что это двойная трата процессорных циклов: копирование и удаление. Правильная команда `find` может занять немного больше человеческого времени, но вы делаете это только один раз. Вы можете использовать команду сотни раз, если вы правильно поняли. Telemachus 15 лет назад 0
@Telemachus - правда, но это то, что компьютеры (должны быть) хороши - делать сложные вещи, поэтому нам не нужно! В самом деле - какой вред в том, чтобы копировать некоторые файлы только для того, чтобы вскоре после этого удалить их, если это означает, что команды, которые вы изобрели для этого, очень просты? Steve Folly 15 лет назад 0
@ Стив: нет никакого вреда, правда. Насколько это возможно, это прекрасное решение. Он следует одному принципу, который мне нравится: «Делай самую простую вещь, которая работает». С другой стороны, это нарушает еще один принцип, который мне нравится еще больше: «Изучай свои инструменты». Я бы предпочел узнать, как лучше использовать `find`, чтобы мне не пришлось это делать. Но вы правы: в этом решении нет ничего плохого. Telemachus 15 лет назад 0
@Telemachus: я согласен с "Изучите свои инструменты". Когда я начинал, я уверен, что моя команда поиска выше выглядела бы очень загадочно для меня :-) Steve Folly 15 лет назад 0
0
Nick Stinemates

Не забудьте grep -v

find . | grep -v .svn 
Эта команда не делает то, что вы думаете, что она делает. Juan A. Navarro 13 лет назад 0
0
devXen

You can also do the opposite. Copy everything then delete .svn folders using the below command:

find . | grep ".svn" | xargs rm -rf