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.