Salin semua file dan folder kecuali file dan folder subversi pada OS X

14

Saya mencoba menyalin semua file dan folder dari satu direktori ke direktori lain, tetapi mengecualikan file tertentu. Secara khusus, saya ingin mengecualikan file dan folder subversi. Namun, saya ingin solusi umum namun ringkas.

Saya membayangkan saya akan menemukan kebutuhan untuk mengecualikan beberapa jenis file dalam waktu dekat. Misalnya, saya mungkin ingin mengecualikan .svn, * .bak, dan * .prj.

Inilah yang saya buat untuk itu, tetapi tidak berhasil untuk saya. Bagian pertama, temukan karya, tapi saya melakukan kesalahan dengan xargs dan cp . Saya mencoba cp dengan dan tanpa -R. Juga, saya menggunakan OS X dan tampaknya memiliki versi xargs yang kurang fitur daripada sistem linux.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory
Michael Prescott
sumber
Saya mungkin salah, tetapi saya pikir ini lebih sulit daripada yang Anda pikirkan. Bahkan jika Anda findperintah benar menggunakan -pruneuntuk mengecualikan svn item, Anda kemudian lulus -Rbendera untuk cpyang memberitahu bahwa perintah untuk menjadi rekursif. Ketika itu terjadi, Anda kehilangan rincian apa pun yang Anda miliki dalam findperintah. Saya akan mengotak-atik ini sebentar, tapi saya pikir jawabannya adalah tidak menggunakan -Rdalam cpperintah.
Telemachus
Tampaknya bekerja untuk saya di sistem Linux. Bisakah Anda lebih spesifik tentang apa artinya "tidak berfungsi"? Ada pesan kesalahan? File mendapatkan / tidak mendapatkan salinan yang Anda harapkan?
Dijeda sampai pemberitahuan lebih lanjut.
Ini -Rbenderanya, saya cukup yakin. Hapus itu dan Anda harus baik-baik (meskipun Anda mungkin ingin menambahkan -mindepth 1mengabaikan direktori toplevel folder yang Anda tidak ingin menyalin, saya berasumsi)
Telemachus
Saya biasanya melakukan hal-hal ini dengan menyalin semuanya, dan kemudian menghapus file yang tidak diinginkan di direktori target. Itu seringkali jauh lebih sederhana.
Jan Doggen

Jawaban:

22

(Diedit setelah membaca kembali pertanyaan. Penanya mengatakan rsync tidak diinstal)

Kemungkinan masalah dengan solusi find / xargs Anda adalah spasi pada nama file. Untuk menyiasatinya, beri tahu find dan xargs untuk menggunakan karakter nol (ASCII 0) untuk memisahkan file yang ditemukan:

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

Jika Anda menemukan bahwa rsync tersedia, saya masih berpikir bahwa rsync adalah solusi yang jauh lebih baik:

Gunakan rsync dengan opsi -C. Dari halaman manual rsync :

Ini adalah singkatan berguna untuk mengecualikan berbagai file yang Anda sering tidak ingin mentransfer antar sistem. Ini menggunakan algoritma yang mirip dengan CVS untuk menentukan apakah file harus diabaikan.

Ini akan memberitahu rsync untuk mengabaikan pola-pola ini:

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/

Sebagai contoh:

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

(catatan: Jika Anda belum terbiasa dengan rsync, pastikan untuk membaca di halaman manual itu tentang bagaimana rsync berurusan dengan garis miring di jalur sumber. Berperilaku berbeda jika Anda memasukkan garis miring daripada jika Anda tidak. Cari 'trailing slash')

Doug Harris
sumber
Oh tikus, saya baru saja membaca kembali pertanyaan Anda dan melihat bahwa Anda mengatakan Anda belum menginstal rsync. Di MacBook Pro (OS X 10.6.1) saya ada di / usr / bin / rsync. Itu diinstal untuk saya di bawah Tiger (10.4) dan Leopard (10.5) juga.
Doug Harris
Saya cukup yakin bahwa Anda (dan OP) tidak ingin -Rbendera di xargsbagian perintah.
Telemachus
Bagus, saya menyalinnya dari pertanyaan awal. Akan diedit sekarang.
Doug Harris
1
Doug terima kasih! Satu hal yang saya khotbahkan, "gunakan alat yang tepat untuk pekerjaan itu". Saya baru-baru ini datang dari dunia Windows ke OSX dan masih meraba-raba dalam ketidaktahuan. Saya memposting pertanyaan yang sama di saluran linux dan seseorang dengan cepat berkata, cukup gunakan "rsynch" Saya mengetik "rsynch" di terminal dan melihatnya tidak ada dan terus menyelidiki temuan | pendekatan xargs. Saya agak keras kepala seperti itu. Bagaimanapun, OSX memang memiliki "rsync" secara default, dan postingan Anda sangat membantu. Saya belum memiliki pengalaman yang cukup di sini untuk mengetahui mana yang lebih baik, tetapi rsync tentu jauh lebih ringkas. Terima kasih!
Michael Prescott
Jika Anda akan melakukan pekerjaan apa pun dengan mesin linux selain pekerjaan Anda di OS X, saya pikir Anda akan merasa sepadan dengan waktu Anda untuk belajar bagaimana menggunakan rsync. Fungsionalitas utamanya adalah penyalinan yang cerdas dari hanya barang yang diubah (seperti robocopy di windows, jika Anda terbiasa dengan itu). Karena hanya menyalin delta, itu cara yang bagus untuk menangani backup (non-Time Machine), penyebaran kode dan sejenisnya.
Doug Harris
2

Bukan solusi umum tetapi ... Anda dapat menggunakan perintah ekspor svn untuk membuat salinan ruang kerja tanpa folder metadata .svn.

Chris Nava
sumber
Tidak menyinggung, tapi saya tidak yakin mengapa jawaban ini semakin banyak dipilih. Saya menyadari kemampuan svn, tetapi "Saya ingin solusi umum namun ringkas. Saya kira saya akan menemukan kebutuhan untuk mengecualikan beberapa jenis file dalam waktu dekat"
Michael Prescott
2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

jika mau, Anda bahkan dapat menempatkan 'pv' atau yang serupa di antara proses 2 tar.

akira
sumber
2

Cara kotor tapi cepat dan ringkas:

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

Ini menyalin satu direktori ke direktori lain (dengan demikian opsi rekursif -r) dan kemudian secara rekursif menghapus apa pun yang dinamai .svn(mengabaikan kasing).

michele
sumber
1

Saya akan melakukannya dengan cara yang berbeda, menggunakan tar dan mekanisme pengecualiannya.

Dari di direktori tujuan:

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

Ini akan cd untuk sumber, tar konten, tidak termasuk apa yang tercantum dalam excludefile, dan kemudian untar ke direktori saat ini.

KeithB
sumber
Solusi elegan memang.
Nick Stinemates
baik, itu jawaban yang sama yang saya berikan, baru nanti. plus Anda harus berada di direktori tujuan ... :)
akira
0

Jawaban yang diedit : Masalahnya adalah -Rmembuat salinan Anda rekursif dan akhirnya Anda menyalin file yang tersembunyi. Inilah yang akan saya gunakan:

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

The -mindepth 1bendera mengatakan finduntuk mengabaikan direktori tingkat teratas. Karena Anda ingin menyalin semua konten direktori itu ke direktori tingkat atas baru, saya berasumsi Anda tidak menginginkannya.

Seperti yang dikatakan Chris Nava dalam jawabannya , sudah ada cara bawaan untuk melakukan ini jika kita berbicara tentang folder SVN, tetapi karena Anda meminta solusi yang lebih umum, ini mungkin sedikit membantu.

Telemakus
sumber
Terima kasih Telemachus, ini sangat membantu. Saya tidak memiliki pengalaman untuk mengkritik, tetapi saya akan mengulangi apa yang telah saya katakan sejak posting asli saya. "xargs sudah rusak" Komentator irc yang tidak dikenal yang memberi tahu saya bahwa mengilhami saya untuk melihat-lihat lebih sedikit dan saya pikir jawaban Doug Harris mengatasi masalah tersebut. Itu memberi tahu xargs untuk menggunakan karakter nol. Saya pikir itu adalah saklar -0?
Michael Prescott
@Michael: xargstidak rusak, tetapi pada sistem mirip Unix, defaultnya adalah tidak menggunakan nama file (atau nama direktori) dengan spasi di dalamnya. Jika Anda memiliki spasi atau karakter "lucu" dalam nama file Anda (atau nama direktori), maka Anda harus melakukan pekerjaan ekstra untuk menghadapinya. (Dalam GNU find, ada seluruh bagian di manhalaman yang disebut "FILENAMEN TIDAK BIASA" karena masalah ini.) -0Bendera masuk xargsdan -print0untuk findbantuan untuk menangani masalah ini. Namun, saya berjanji kepada Anda bahwa Anda tidak ingin menggunakannya -Rdalam perintah penyalinan Anda. Ini akan membatalkan apa pun yang Anda lakukan untuk menghindari direktori SVN.
Telemachus
0

Saya kira itu tergantung seberapa besar pohon Anda, tetapi mengapa tidak hanya menyalin semuanya dulu, lalu pangkas folder .svn setelah:

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

?

Steve Folly
sumber
Tanpa pembandingan, pemikiran awal saya adalah bahwa ini adalah pemborosan siklus CPU: menyalin dan menghapus. Mungkin butuh sedikit waktu ekstra manusia untuk menyusun findperintah yang tepat , tetapi Anda hanya melakukannya sekali. Anda dapat menggunakan perintah ratusan kali, setelah Anda melakukannya dengan benar.
Telemachus
@ Selemachus - benar, tapi itulah yang membuat komputer (seharusnya) bagus - melakukan hal-hal yang rumit sehingga kita tidak perlu melakukannya! Sungguh - apa salahnya menyalin beberapa file hanya untuk menghapusnya segera setelah itu, jika itu berarti perintah yang Anda buat untuk melakukannya sangat sederhana?
Steve Folly
@ Steve: tidak ada salahnya, sungguh. Sejauh ini, ini adalah solusi yang bagus. Ini mengikuti satu prinsip yang saya sukai: "Lakukan hal sesederhana mungkin yang berhasil." Di sisi lain, itu melanggar prinsip lain yang lebih saya sukai: "Pelajari alat Anda." Saya lebih suka belajar bagaimana menggunakannya dengan findlebih baik, sehingga saya tidak perlu melakukan ini. Tapi Anda benar: tidak ada yang salah dengan solusi ini.
Telemakus
@Telemachus: Saya setuju dengan "Pelajari alat Anda". Ketika saya mulai keluar, aku yakin perintah find saya di atas akan tampak sangat samar untuk saya maka :-)
Steve Folly
0

Jangan lupa grep -v

find . | grep -v .svn
Nick Stinemates
sumber
Perintah ini tidak melakukan apa yang Anda pikir sedang dilakukan.
Juan A. Navarro
0

Anda juga bisa melakukan yang sebaliknya. Salin semuanya kemudian hapus folder .svn menggunakan perintah di bawah ini:

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