Linux: Diz ve alt dizinlerden eşleşen tüm dosyaları tek bir dizine kopyala


31

Bütün kopyalamak isteseydim *.sodosyaları srciçin dstyapardım:

cp src/*.so dst

Ancak, ben her kopyalamak istediğiniz *.sosrc dosya ve 's subdirs içine dst. Herhangi bir ipucu var mı?

Yanıtlar:


36

Deneyin:

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

17
findDesen eşleştirme yapabilir ve komutları çalıştırabilir. find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'
— Çıktısını aktarmaya

1
Evet, bir boru hattını okumak genellikle daha kolaydır, aynı zamanda parametre eşleştirmesinde grepkullanılan basit kabuk modellerinden daha ağır olan örnek eşleştirme özellikleri de daha kolaydır . ayrıca, parametresinden çok daha güçlüdür . -namefindxargs-execfind
— Mike Insch

2
@Jaquer çözümü çok daha iyi çünkü MacOSX xargs programında -i seçeneği bulunmuyor. Ancak onun çözümü bir cazibe gibi çalışır.
— bialix

Mac'imde mükemmel çalışan jaquer'in çözümü ile ilgili olarak bialix'in yorumunu okuyana dek -i argümanındaki xargs argümanı ile ilgili bir hata mesajı ile mücadele ediyordum. Thanks
— svannoy

Bu, gerektiğinde alt dizinler oluşturur mu?
— Lennart Rolland

15

Bash kullanıyorsanız, dosyaları ve dizinleri tekrar tekrar eşleştirmek için globstar kabuk seçeneğini açabilirsiniz :

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

Adlarıyla başlayan dosyaları .ve / veya adları ile başlayan dizinlerin içindeki ve altındaki dosyaları bulmanız gerekiyorsa ., dotglobseçeneği de (örneğin, ile shopt -s dotglob) ayarlayın. İkisini de tek bir komutla ayarlayabilirsiniz:

shopt -s globstar dotglob

Bir ile başlayan alt dizinlerdeki dosyaları kopyalamaz. kendi adına
— rboy

8

Mike tarafından önerilen komutu denedim:

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

ancak tüm dosyaları dstgöreceli yolları kaybedilmiş şekilde dizine dökmekle sonuçlandı .

Göreceli yolları korumak için komutun buna göre değiştirilmesi gerekir:

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

7
+1. Ancak, bu göreceli kaynak yollarına karşılık gelen dizinlerin altında olduğunu varsayar dst. Öyle olmadığı takdirde kullanın cp --parents. Ayrıca, dosya adlarını alıntı yaptığınızdan emin olun. Böylece: ... | xargs -i cp --parents "{}" dst(son argümanın cpşimdi hedef dizinin "sadece" olduğunu unutmayın ). -t: Bayrağı ile komut daha da kısa (ve muhtemelen daha hızlı) yapılabilir ... | xargs cp --parents -t dst.
— Stephan202

1
@ Stephan202 kullanmak zorunda kaldım... | xargs cp {} --parents -t dst.
— warvariuc

Mac’te olanlar için --parentsmevcut değil. dittoOnun yerine kullandım : stackoverflow.com/questions/11246070/cp-parents-option-on-mac
— Bryan Young

3

Bunu yapmanın başka bir yolu şudur:

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

Ve bu sayısını azaltmak gerekir cpsüreçler: ... -exec cp -t dst/ {} +.
— Kamil Maciorowski

Selam Kamil! Yorum için teşekkürler! Lütfen çözümünüzün işleri nasıl daha hızlı hale getirdiğini açıklayabilir misiniz? Her zaman daha fazla bilgi edinmek istekli :)
— Kyriakos

Eğer bitirdiğinizde -execile ;, {}her seferinde bir yol ile değiştirilir. cpHer dosya için ayrı bir dosya alıyorsunuz . İle +sözdizimi findyerine geçer {}birden çok sonuç (komut hattı uzunluğunun bir sistem tanımlı bir sınıra kadar, sınırlama: {}önceki son şey olması gerekir +, dolayısıyla cp -t). Bir sürecin yaratılması ve sonlandırılması nispeten maliyetli bir şeydir. Bu nedenle, +çok fazla sonuç beklediğinizde kullanmak iyidir . Bu durumda, çok sayıda dosyayı kopyalamak yine de çok zaman alabilir, bu nedenle fark fark edilmeden geçebilir; Bununla birlikte, bu iyi bir uygulamadır.
— Kamil Maciorowski

1

Grep, find -name kullanılarak değiştirilebilir :

find src/ -type f -name "*.so" | xargs -i cp {} dst/{}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.