Linux: Salin semua pola pencocokan file dari dir dan subdir ke dalam satu dir


31

Jika saya ingin menyalin semua *.sofile dari srcke dstsaya akan lakukan:

cp src/*.so dst

Namun, saya ingin menyalin semua *.sofile dari src dan subdirs itu ke dalam dst. Ada petunjuk?

Jawaban:


36

Mencoba:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

17
finddapat melakukan pencocokan pola dan menjalankan perintah. Tidak perlu menyalurkan outputnya:find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'
— jáquer

1
Ya, itu bisa, namun seringkali lebih mudah untuk membaca pipeline, juga kemampuan pencocokan pola grepjauh melebihi pola shell sederhana yang digunakan dalam -nameparameter find. xargsjuga jauh lebih kuat daripada -execparameter untuk find.
— Mike Insch

2
Solusi @jaquer jauh lebih baik karena pada MacOSX xargs utility tidak memiliki opsi -i. Tapi solusinya bekerja seperti pesona.
— bialix

Saya kesulitan dengan pesan kesalahan pada argumen -i ke xargs sampai saya membaca komentar dari @bialix mengenai solusi jaquer, yang bekerja dengan baik di Mac saya. Terima kasih
— svannoy

Apakah ini akan membuat subdirektori sesuai kebutuhan?
— Lennart Rolland

15

Jika Anda menggunakan Bash, Anda dapat mengaktifkan globstar opsi shell untuk mencocokkan file dan direktori secara rekursif:

shopt -s globstar
cp src/**/*.so dst

Jika Anda perlu menemukan file yang namanya dimulai dengan ., dan / atau file di dalam dan di bawah direktori yang namanya dimulai ., tetapkan dotglobjuga opsi (misalnya dengan shopt -s dotglob). Anda dapat mengatur keduanya dalam satu perintah:

shopt -s globstar dotglob

Tidak menyalin file dalam subdirektori yang dimulai dengan a. dalam nama mereka
— rboy

8

Saya mencoba perintah yang disarankan oleh Mike:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

tetapi berakhir dengan membuang semua file ke direktori dstdengan jalur relatif mereka hilang.

Untuk menjaga path relatif, perintah perlu dimodifikasi untuk ini:

find src/ -type f | grep -i so$ | xargs -i cp {} dst/{}

7
+1. Namun, ini mengasumsikan bahwa direktori yang sesuai dengan jalur sumber relatif ada di bawah dst. Jika tidak, gunakan cp --parents. Juga, pastikan untuk mengutip nama file. Jadi: ... | xargs -i cp --parents "{}" dst(perhatikan bahwa argumen terakhir cpadalah "hanya" direktori tujuan). Perintah dapat dibuat lebih pendek (dan mungkin lebih cepat) menggunakan -tbendera: ... | xargs cp --parents -t dst.
— Stephan202

1
@ Stephan202 Saya harus menggunakan... | xargs cp {} --parents -t dst.
— warvariuc

bagi mereka yang menggunakan mac, --parentstidak tersedia. Saya menggunakan dittotempatnya: stackoverflow.com/questions/11246070/cp-parents-option-on-mac
— Bryan Young

3

Cara lain untuk melakukan ini adalah seperti ini:

find src/ -type f -name "*.so" -exec cp {} dst/ \;

Dan ini harus mengurangi jumlah cpproses: ... -exec cp -t dst/ {} +.
— Kamil Maciorowski

Hai Kamil! Terima kasih atas komentarnya! Bisakah Anda jelaskan bagaimana solusi Anda membuat segalanya lebih cepat! Selalu bersedia untuk belajar lebih banyak :)
— Kyriakos

Ketika Anda berakhir -execdengan ;, {}digantikan oleh satu jalur pada suatu waktu. Anda mendapatkan terpisah cpuntuk setiap file. Dengan +sintaks finddiganti {}dengan beberapa hasil (hingga batas panjang baris perintah yang ditentukan sistem; pembatasan: {}harus menjadi hal terakhir sebelumnya +, karenanya cp -t). Menciptakan dan mengakhiri suatu proses adalah hal yang relatif mahal. Untuk alasan ini, ada baiknya digunakan +kapan saja Anda mengharapkan banyak hasil. Dalam hal ini, menyalin banyak file mungkin memerlukan banyak waktu sehingga perbedaannya dapat berlalu tanpa diketahui; namun itu praktik yang baik.
— Kamil Maciorowski

1

Grep dapat diganti dengan menggunakan find's -name :

find src/ -type f -name "*.so" | xargs -i cp {} dst/{}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.