Скопіюйте всі файли та папки, крім підривних файлів і папок в ОС X


14

Я намагаюся скопіювати всі файли та папки з одного каталогу в інший, але виключаю певні файли. Зокрема, я хочу виключити підривні файли та папки. Однак я хотів би загального, але стислого рішення.

Я думаю, я знайду необхідність виключити кілька типів файлів найближчим часом. Наприклад, я можу захотіти виключити .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. З сторінки man 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

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

Хороший улов, я скопіював це з оригінального запитання. Відредагуйте зараз.
Doug Harris

1
Дякую Дугу! Я проповідую одне, «використовувати правильний інструмент для роботи». Нещодавно я прийшов зі світу Windows в OSX і все ще блукаю в незнанні. Я опублікував це те саме питання на каналі linux, і хтось швидко сказав, просто використовуйте "rsynch" Я набрав "rsynch" в терміналі і побачив, що його не існує, і продовжував розслідувати знахідку | xargs підхід. Я трохи впертий такий. У будь-якому випадку, OSX має "rsync" за замовчуванням, і ваш пост був дуже корисним. Тут у мене ще недостатньо досвіду, щоб знати, що краще, але rsync впевнений, набагато більш стислий. Спасибі!
Майкл Прескотт,

Якщо ви будете займатися будь-якою роботою з Linux-машинами на додаток до роботи над OS X, я думаю, ви вважаєте, що це варто свого часу, щоб навчитися користуватися rsync. Основна його функціональність - це інтелектуальне копіювання лише змінених речей (наприклад, роботокопія на Windows, якщо ви з цим знайомі). Оскільки він копіює лише дельту, це прекрасний спосіб обробляти резервні копії, розгортання коду тощо.
Дуг Гарріс

2

Не загальні рішення, але ... ви можете використовувати команду експорту svn для створення копії робочої області без папок метаданих .svn.


Не образливо, але я не впевнений, чому ця відповідь стає голосною. Я знаю про можливості svn, але "я хотів би загального, але стислого рішення. Я думаю, я знайду необхідність виключити декілька типів файлів найближчим часом"
Майкл Прескотт,

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

якщо ви хочете, ви можете навіть помістити "pv" або щось подібне між двома процесами tar.


2

Брудний, але швидкий і стислий спосіб:

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

Це копіює один каталог в інший (таким чином, рекурсивний варіант -r), а потім рекурсивно видаляє все, що називається .svn(ігноруючи випадок).


1

Я б пішов про це по-іншому, використовуючи дьоготь та його механізм виключення.

З в каталозі призначення:

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

Це додасть CD-код до джерела, відзначить вміст, виключаючи те, що вказано у файлі exceefile, та відкиньте його до поточного каталогу.


Елегантне рішення справді.
Нік Stinemates

ну, це та сама відповідь, яку я і дав, трохи пізніше. плюс ви повинні бути в каталозі призначення ... :)
akira

0

Відредагована відповідь : Проблема полягає в тому, що -Rваше копіювання стає рекурсивним, і тому ви закінчуєте копіювати приховані файли. Ось що я б використав:

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

-mindepth 1Прапор вказує findігнорувати каталог верхнього рівня. Оскільки ви хочете скопіювати весь вміст цього каталогу в новий каталог топлев, я припускаю, що ви цього не хочете.

Як говорить Кріс Нава у своїй відповіді , вже є вбудований спосіб зробити це, якщо ми говоримо про папки SVN, але оскільки ви попросили більш загальне рішення, це може трохи допомогти.


Дякую Телемаху, це корисно. У мене немає досвіду критикувати, але я повторю те, про що мені говорили з мого початкового поста. "xargs islom" Невідомий коментатор 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 - правда, але це те, в чому комп'ютери (мабуть, добре) - роблять складні речі, тому нам не доведеться! Дійсно - яка шкода в копіюванні деяких файлів лише для того, щоб вони були видалені незабаром після, якщо це означає, що команди, які ви винаходили, зробити це дуже просто?
Стів Фоллі

@Steve: насправді немає шкоди. Наскільки це йде, це прекрасне рішення. Він дотримується одного принципу, який мені подобається: "Зробіть найпростішу можливу річ, яка працює". З іншого боку, це порушує інший принцип, який мені подобається ще більше: "Вивчіть свої інструменти". Я вважаю за краще навчитися використовувати findсебе краще, щоб мені не довелося цього робити. Але ви праві: з цим рішенням нічого поганого немає.
Телемах

@ Telemachus: Я згоден із "Дізнайтеся свої інструменти". Коли я розпочав свою роботу, я впевнений, що моя команда знаходження вище виглядала б для мене дуже крикливою :-)
Стів Фоллі


0

Ви також можете зробити навпаки. Скопіюйте все, а потім видаліть .svn папки за допомогою команди нижче:

find . | grep ".svn" | xargs rm -rf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.