Skopiuj wszystkie pliki i foldery z wyjątkiem plików i folderów subversion w OS X

14

Próbuję skopiować wszystkie pliki i foldery z jednego katalogu do drugiego, ale wykluczam niektóre pliki. W szczególności chcę wykluczyć pliki i foldery subversion. Chciałbym jednak ogólne, ale zwięzłe rozwiązanie.

Wyobrażam sobie, że w najbliższej przyszłości będę musiał wykluczyć kilka rodzajów plików. Na przykład mogę wykluczyć .svn, * .bak i * .prj.

Oto, po co to przygotowałem, ale to nie działa dla mnie. Pierwsza część, znajdź działa, ale robię coś złego z xargs i cp . Próbowałem cp zi bez -R. Ponadto używam OS X i wygląda na to, że ma mniej polecaną wersję Xargsa niż systemy Linux.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory
Michael Prescott
źródło
Mogę się mylić, ale myślę, że jest to trudniejsze niż myślisz. Nawet jeśli twoje findpolecenie prawidłowo używa -prunedo wykluczenia elementów .svn, to przekazujesz -Rflagę, cpktóra mówi, że to polecenie ma być rekurencyjne. Kiedy tak się dzieje, tracisz wszelką ziarnistość, jaką posiadasz w findpoleceniu. Będę majstrować przy tym przez chwilę, ale myślę, że odpowiedzi nie należy używać -Rw cppoleceniu.
Telemachus
Wydaje się, że działa dla mnie w systemie Linux. Czy możesz sprecyzować, co oznacza „to nie działa”? Jakieś komunikaty o błędach? Pliki są kopiowane / nie są oczekiwane?
Wstrzymano do odwołania.
To -Rflaga, jestem całkiem pewien. Usuń to i powinieneś być w porządku (choć możesz chcieć dodać, -mindepth 1aby zignorować folder katalogu najwyższego poziomu, którego nie chcesz kopiować, zakładam)
Telemachus
Zwykle robię te rzeczy, kopiując wszystko, a następnie usuwając niechciane pliki z katalogów docelowych. Często jest to o wiele prostsze.
Jan Doggen

Odpowiedzi:

22

(Edytowane po ponownym przeczytaniu pytania. Pytający mówi, że rsync nie jest zainstalowany)

Możliwym problemem z rozwiązaniem find / xargs są spacje w nazwach plików. Aby obejść ten problem, powiedz find i xargs, aby użyły znaku zerowego (ASCII 0) do rozdzielenia znalezionych plików:

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

Jeśli okaże się, że rsync jest dostępny, nadal uważam, że rsync jest zdecydowanie lepszym rozwiązaniem:

Użyj rsync z opcją -C. Ze strony man rsync :

Jest to przydatny skrót do wykluczania szerokiej gamy plików, których często nie chcesz przenosić między systemami. Wykorzystuje algorytm podobny do CVS, aby ustalić, czy plik powinien zostać zignorowany.

Spowoduje to, że rsync zignoruje następujące wzorce:

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/

Na przykład:

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

(uwaga: jeśli jeszcze nie znasz zbytnio rsync, przeczytaj na tej stronie podręcznika o tym, jak rsync radzi sobie z końcowym ukośnikiem na ścieżce źródłowej. Zachowuje się inaczej, jeśli umieścisz ukośnik niż w innym przypadku. Wyszukaj „trailing slash”)

Doug Harris
źródło
Och, szczury, ponownie przeczytałem twoje pytanie i zobaczyłem, że powiedziałeś, że nie masz zainstalowanego rsync. Na moim MacBooku Pro (OS X 10.6.1) jest on w / usr / bin / rsync. Został również zainstalowany dla mnie pod Tiger (10.4) i Leopard (10.5).
Doug Harris
Jestem prawie pewien, że ty (i OP) nie chcesz -Rflagi w xargsczęści polecenia.
Telemachus
Dobry połów, skopiowałem to z pierwotnego pytania. Będzie edytować teraz.
Doug Harris
1
Dzięki, Doug! Głoszę jedną rzecz: „użyj odpowiedniego narzędzia do pracy”. Niedawno przeszedłem ze świata Windows na OSX i wciąż szukam ignorancji. Zadałem to samo pytanie na kanale linuksowym i ktoś szybko powiedział, po prostu użyj „rsynch” W terminalu wpisałem „rsynch” i zobaczyłem, że nie istnieje, i kontynuowałem badanie znaleziska | podejście xargs. Jestem taki uparty. W każdym razie OSX ma domyślnie „rsync”, a twój post był bardzo pomocny. Nie mam jeszcze wystarczającego doświadczenia, aby wiedzieć, co jest lepsze, ale rsync na pewno jest o wiele bardziej zwięzły. Dzięki!
Michael Prescott
Jeśli oprócz pracy nad systemem OS X będziesz wykonywać jakąkolwiek pracę z komputerami z systemem Linux, myślę, że warto poświęcić czas na naukę korzystania z rsync. Jego podstawową funkcjonalnością jest inteligentne kopiowanie tylko zmienionych elementów (np. Robocopy w systemie Windows, jeśli jesteś z tym zaznajomiony). Ponieważ kopiuje tylko różnicę, jest to świetny sposób na obsługę kopii zapasowych (innych niż Time Machine), wdrażania kodu i tym podobnych.
Doug Harris
2

Nie jest to ogólne rozwiązanie, ale ... możesz użyć polecenia svn export, aby utworzyć kopię obszaru roboczego bez folderów metadanych .svn.

Chris Nava
źródło
Nie chcę być obraźliwy, ale nie jestem pewien, dlaczego ta odpowiedź zyskuje na głosowaniu. Zdaję sobie sprawę z możliwości svn, ale „Chciałbym ogólne, ale zwięzłe rozwiązanie. Wyobrażam sobie, że w najbliższej przyszłości będę musiał wykluczyć kilka rodzajów plików”
Michael Prescott,
2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

jeśli chcesz, możesz nawet umieścić „pv” lub coś podobnego pomiędzy 2 procesami tar.

akira
źródło
2

Brudny, ale szybki i zwięzły sposób:

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

Spowoduje to skopiowanie jednego katalogu do drugiego (a więc opcja rekurencyjna -r), a następnie rekurencyjne usunięcie wszystkiego o nazwie .svn(ignorowanie wielkości liter).

michele
źródło
1

Postąpiłbym inaczej, używając tar i mechanizmu wykluczającego.

Z w katalogu docelowym:

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

Spowoduje to cd do źródła, tarowanie zawartości, z wyłączeniem tego, co jest wymienione w excludefile, a następnie rozpakowanie do bieżącego katalogu.

KeithB
źródło
Rzeczywiście eleganckie rozwiązanie.
Nick Stinemon,
cóż, to ta sama odpowiedź, którą udzieliłem, tylko później. plus musisz być w katalogu docelowym ... :)
akira
0

Zredagowana odpowiedź : Problem polega na tym, -Rże kopiowanie jest rekurencyjne, więc w rezultacie kopiujesz ukryte pliki. Oto czego użyłbym:

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

-mindepth 1Flag opowiada findignorować katalogu Toplevel. Ponieważ chcesz skopiować całą zawartość tego katalogu do nowego katalogu najwyższego poziomu, zakładam, że tego nie chcesz.

Jak mówi Chris Nava w swojej odpowiedzi , istnieje już wbudowany sposób, aby to zrobić, jeśli mówimy o folderach SVN, ale ponieważ poprosiłeś o bardziej ogólne rozwiązanie, może to trochę pomóc.

Telemachus
źródło
Dzięki Telemachusowi jest to pomocne. Nie mam doświadczenia w krytykowaniu, ale powtórzę to, co powiedziano mi od czasu mojego pierwszego postu. „xargs jest zepsuty” Nieznany komentator IRC, który powiedział mi, że zainspirował mnie do dalszego rozejrzenia się i myślę, że odpowiedź Douga Harrisa rozwiązuje ten problem. Mówi xargsowi, aby używał znaków zerowych. Myślę, że to jest przełącznik -0?
Michael Prescott
@ Michael: xargsnie jest zepsuty, ale w systemach uniksowych domyślnie nie używa się nazw plików (lub nazw katalogów) ze spacjami w nich. Jeśli w nazwach plików (lub nazwach katalogów) znajdują się spacje lub „śmieszne” znaki, musisz wykonać dodatkową pracę, aby sobie z tym poradzić. (W GNU find, istnieje cała sekcja na manstronie o nazwie „Unusual NAZWY PLIKÓW” z powodu tego problemu.) Do -0flagi xargsi -print0za findpomoc do rozwiązania tych problemów. Obiecuję ci jednak, że nie chcesz używać -Rpolecenia kopiowania. Cofnie to, co zrobisz, aby uniknąć katalogów SVN.
Telemachus
0

Przypuszczam, że to zależy od tego, jak duże jest twoje drzewo, ale dlaczego nie po prostu najpierw skopiować wszystko , a następnie przyciąć foldery .svn po:

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

?

Steve Folly
źródło
Bez żadnego testu porównawczego, początkowo myślałem, że jest to podwójne marnowanie cykli procesora: kopiowanie i usuwanie. Stworzenie właściwego findpolecenia może zająć trochę więcej czasu , ale robisz to tylko raz. Możesz użyć polecenia setki razy, gdy już dobrze je wykonasz.
Telemachus
@Telemachus - prawda, ale właśnie w tym komputery są (powinny być) dobre - robiąc podchwytliwe rzeczy, więc nie musimy! Naprawdę - jaka szkoda wiąże się z kopiowaniem niektórych plików tylko po to, aby zostały usunięte wkrótce, jeśli oznacza to, że polecenia, które wymyśliłeś, są bardzo proste?
Steve Folly
@ Steve: naprawdę nie ma nic złego. Jeśli chodzi o to, jest to dobre rozwiązanie. Kieruje się jedną zasadą, którą lubię: „Zrób najprostszą możliwą rzecz, która działa”. Z drugiej strony narusza to inną zasadę, którą lubię jeszcze bardziej: „Naucz się swoich narzędzi”. Wolałbym nauczyć się, jak korzystać z findsiebie lepiej, aby nie musiałem tego robić. Ale masz rację: w tym rozwiązaniu nie ma nic złego.
Telemachus
@Telemachus: Zgadzam się z „Naucz się swoich narzędzi”. Kiedy zaczynałem, jestem pewien, że moje polecenie znajdowania powyżej wyglądałoby dla mnie bardzo tajemniczo :-)
Steve Folly
0

Nie zapomnij grep -v

find . | grep -v .svn
Nick Stinemon
źródło
To polecenie nie działa tak, jak myślisz.
Juan A. Navarro,
0

Możesz także zrobić odwrotnie. Skopiuj wszystko, a następnie usuń foldery .svn za pomocą poniższego polecenia:

find . | grep ".svn" | xargs rm -rf
devXen
źródło