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.