Klasör yapısını koruyarak belirli dosya tipini kopyala


108

Klasörlere dağılmış bir sürü * .csv dosyası içeren bir klasör yapısına sahibim. Şimdi tüm * .csv dosyalarını, klasör yapısını koruyarak başka bir hedefe kopyalamak istiyorum.

Yaparak çalışır:

cp --parents *.csv /target
cp --parents */*.csv" /target
cp --parents */*/*.csv /target
cp --parents */*/*/*.csv /target
...

ve benzerleri, ancak bir komut kullanarak bunu yapmak istiyorum.

Yanıtlar:


126

İnsanların bulduklarını kullanmak için direnmelerinin bir nedeni var -execmı? Çok kullanışlı.

find . -name '*.csv' -exec cp --parents \{\} /target \;

Aletlerini bil. ;-)


62
Muhtemelen bu nedenle \ {\} \;
igo,

12
'{}'aynı şekilde çalışır
OrangeDog

3
Bundan -execdirdaha güvenli olsa da -exec, yalnızca birini diğeriyle değiştirmek, klasör yapısını amaçlandığı şekilde korumaz.
Simon Shine,

2
Neden onları komutunuzla kopyalamaya çalıştığımda 'Dizini atlıyor' mesajı alıyorum?
Vicky Dev

4
Diş tellerinin neden buradan kaçmaları gerektiğini açıklayabilir misiniz?
Noumenon

46

Bunun için de kullanabilirsiniz rsync.

$ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/

Kaynak dizininde boş dizinleri tutmak istiyorsanız, --prune-empty-dirsseçeneği atlayın :

$ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/

Eğer yoksa değil sembolik, değiştirilme tarihleri, dosya izinlerini istiyorum vb sahipleri korunmuş, lütfen değiştirin -abaşka kombinasyonu ile -rlptgoD. ;-)


1
-mkısayol --prune-emty-dirs.
Geremia

Ayrıca, -Rkaynağın ana dizin yapısını kopyalamak için seçenek eklenebilir. (burada cevabım bakınız.)
Geremia

-R benim için çalışıyor! Teşekkürler
gigi2

32

Geçiş modunda find ve cpio kullanabilirsiniz

find . -name '*.csv' | cpio -pdm  /target

Bu, mevcut dizinde ve altındaki tüm .csv dosyalarını bulur ve kök dizin yapısını koruyarak / hedefine kopyalar ..

Eğer kullanırsan

find /path/to/files -name '*.csv' | cpio -pdm /target

tüm dosyayı içeride /path/to/filesve altında bulur ve kopyalar ve altına kopyalar /target/path/to/files.


3
Buna karşılık tüm cevapları denedim ve bu ilk denemede çalışan tek kişiydi
OscarRyz

21

cpKomut çoklu kaynak argümanları izin:

cp **/*.csv --parents ../target

CAVEAT: Burada özyinelemeli bir küre kullanıyorum; Bu, globstarBash 4+' deki seçenektir kshve varsayılan olarak desteklenmektedir zsh. Özyinelemeli glob'lar gizli dosya ve klasörler ile eşleşmiyor ve bazı uygulamalar diğerleri uyuşmazken sembolik izleri takip ediyor .

Kabuğunuz özyinelemeli dünyayı desteklemiyorsa veya onları kullanmamayı tercih ederseniz, aşağıdakileri yapabilirsiniz:

  • *.csv */*.csv */*/*.csv */*/*/*.csv - bu elbette çok gereksiz ve dizin yapınızın ne kadar derin olduğunu bilmenizi gerektirir.
  • $(find . -name '*.csv')- Bu olacak Gizli dosya ve klasörleri maç. findayrıca, yararlı olabilecek sembolik işaretlerin izlenip izlenmeyeceğini belirlemeyi de destekler.

Bu tam olarak ne denedim (özyinelemeli glob) ve bazı ama hepsi değil bulundu? oldukça garip. Npm copyfiles betiğini kullanırken aynı sonucu aldım ancak find komutunu kullanırsam her şeyi bulur ...
Randyaa

@Randyaa Size yardım etmek için hangi dosyaların bulunamadığı konusunda daha fazla ayrıntıya ihtiyacım var. Sen tartışma bulabilirsiniz burada ve sürekli burada yararlı özyinelemeli glob kesin davranış hakkında.
Kyle Strand

1
özyinelemeli glob'un bir sebepten dolayı etkin olmadığı ortaya çıktı ... Daha önce hiç karşılaşmadım, ancak emrimden shopt -s globstarhemen önce bir idamla düzelttim ve her şey yolunda gitti. Takip için teşekkürler!
Randyaa

--parentsaradığım şey buydu. teşekkürler
Josh

17

Bu benim için çalıştı:

find -name "*.csv" | xargs cp --parents -t /target


En basit sözdizimi ile en iyi cevap. Sadece iyi çalışıyor ve hatırlaması kolaydır. Çoğu durumda find [things] | xargs [do stuff]çok güçlü.
Her gün Astronot

Kabul. Diğer cevapların bazılarına göre çok basit.
Tim B,

1
Dosya adlarında boşluk varsa sonları
Michele Piccolini

@MichelePiccolini Dosya isimlerindeki boşluklar find -print0ve ile kullanılabilir xargs -0.
pasztorpisti

8

Eğer bu yapıyı çoğaltmak istediğiniz varsayarsak ./sourceiçin ./destination:

cd source
find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)

Bunu tek bir satır cd sourceolarak ve bir kabuk yerleşik olarak saymaya hazırım .


2
Gerçekten tek bir komut anlamına geldiğini sanmıyorum - sadece onun örneği gibi

tar-Cönce dizini değiştirmek zorunda kalmamak için seçeneğiniz vardır .
bart

8

Gönderen rsyncbireyin manpage:

-R, - göreceli

Göreceli yollar kullanın. Bu, komut satırında belirtilen tam yol adlarının yalnızca dosya adlarının son bölümleri yerine sunucuya gönderildiği anlamına gelir. Bu, aynı anda birkaç farklı dizin göndermek istediğinizde özellikle yararlıdır. Örneğin, bu komutu kullandıysanız:

rsync -av /foo/bar/baz.c remote:/tmp/

... bu, uzak makinede / tmp / dizininde baz.c adında bir dosya oluşturacaktır. Eğer onun yerine kullanılırsa

rsync -avR /foo/bar/baz.c remote:/tmp/

daha sonra, uzak makinede tam yolunu koruyarak /tmp/foo/bar/baz.c adlı bir dosya oluşturulur. Bu ilave yol elemanlarına "zımni dizinler" (yani, yukarıdaki örnekte "foo" ve "foo / bar" dizinleri) denir.

Yani bu da işe yarayacak:

rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
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.