Belirli bir uzantıya sahip tüm dosyaları birden fazla alt dizinden bir dizine taşıyın


42

Birkaç dizinde bir sürü .zip dosyası var:

Fol1/Fol2
Fol3
Fol4/Fol5

Hepsini ortak bir klasöre nasıl taşırım?


Dizin yapısını korumak ister misiniz? Dizinleri mi yoksa sadece zip dosyalarını mı taşımak istiyorsunuz?
Ürdün

Sadece zip dosyalarını taşımak istiyorum. Dizinleri umursamıyorum - tek başlarına bırakılabilir veya silinebilirler.
InquilineKea

Yanıtlar:


54

Zip dosyalarını ( cd …) içeren ağacın üst düzey dizinine gidin , sonra çalıştırın

mv **/*.zip /path/to/single/target/directory

Bu, zsh içindeki kutunun dışında çalışır. Eğer kabuğunuz bash ise, önce koşmanız gerekir shopt -s globstar(bu komutu kendi içine koyabilirsiniz ve koymalısınız ~/.bashrc). Eğer kabuğunuz ksh ise, önce koşmanız gerekir set -o globstar(içine koyun ~/.kshrc).

Alternatif olarak, findözel bir hazırlık olmadan her yerde çalışan, ancak daha karmaşık olan kullanım:

find . -name '*.zip' -exec mv {} /path/to/single/target/directory \;

Daha sonra boş dizinleri kaldırmak istiyorsanız, zsh cinsinden:

rmdir **/*(/^Fod)

Bash veya ksh cinsinden:

rmdir **/*/

ve kaldırılacak boş dizinler olduğu sürece tekrarlayın. Alternatif olarak, herhangi bir kabukta

find . -depth -type d -empty -exec rmdir {} \;

findYukarıdaki ilk komut bash'te işe yaradı, ancak find . -nameçalışmasını sağlamak için vb. Değiştirmek zorunda kaldı .
JeffThompson

1
@Jeff .GNU'yu bulmak için örtük ama diğerleri için değil, açıkça ekledim.
Gilles 'SO- kötü olmayı'

13

Sadece .zipdosyaları taşımak istiyorsanız, gibi bir şey yapabilir

mkdir ./zipfiles
find . -name "*.zip" -exec mv "{}" ./zipfiles \;

3

Eğer kullanıyorsanız bash sürüm 4 veya daha yüksek veya ZSH da özyinelemeli globbing kullanabilirsiniz:

mv **/*.zip /path/to/move/zip/files/to

Bu SADECE dosyaları taşıyacak, bağıl yolları değil, çarpışmalar ortaya çıkabilir.


göreceli yollar ile ne demek istiyorsunuz?
Kunok

2

Bu, sürümleri ne olursa olsun tüm dağıtıcıların çoğunu destekleyen veri ve hatasız hareket ederken güvenlidir. Bu komut alt dizinleri tarar ve ardından yeni hedef dizininize taşır veya kopyalar.

find . -name *.flac -exec mv '{}' "./flac/" ";"
  • Bu komutu, taşımak istediğiniz dosyalarla birlikte alt dizinleri içeren ana dizinde çalıştırın.
  • Davanızda olduğu *.flacgibi herhangi bir şeye geçebileceğiniz yer *.zip. Ya da *.docsadece herhangi bir eklenti çalışır.
  • ve mvdosyaları taşıma komutu ya da taşımak cpyerine verileri kopyalamak için kullanabilirsiniz .
  • ./flac/tüm FLAC dosyalarını taşımak istediğim hedef dizin. Ayrıca gibi tam bir yol verebilirsiniz/home/myid/flac/

Tam örnek (bu durumda, müzik sanatçısı adında birçok alt dizin vardır /home/myid/Music/ve sonra FLAC dosyaları farklı alt dizinler düzeyindedir. Çünkü sanatçı klasörlerine ihtiyacım yok, ancak tüm FLAC dosyalarının bir dizinde olmasını istiyorum./home/myid/Music/flac/

cd /home/myid/Music
mkdir flac
find . -name *.flac -exec mv '{}' "./flac/" ";"
cd flac
ls

Sonra tüm FLAC dosyalarını gösterecektir.


ne gelmez ;mi?
Francesco Boi

@FrancescoBoi aynı satırdaki bash komutunun işini bitirmesini beklediğinizden emin olun. ve sonra bir sonraki bash komutu satırına geçin. Bu, .pl veya python gibi betikleri içeren komutlar için kullanışlıdır, çünkü bash onu çalıştıracak ve sonra bir sonraki satıra atlayacaktır; Zaman veya komut alan komutlardan sonra, bash bunu atlarsa diye.
Seandex

0

Bir basma kesmek olarak, gücünü kullanabilirsiniz tar:

(cd origin/;find . -exec file --mime-type "{}" \;|grep "application/zip"|cut -d ':' -f 1|xargs tar cf -)|(cd target/; tar xf -) && rm -fr origin/

Bu, dosya uzantılarına bağlı olmaması avantajına sahiptir, çünkü filetaşınacak dosyaları seçme komutunu kullanır ve dizin yapısını korur, ancak boşluk içeren yollarla çalışmaz.

Nihai rmsadece (o yorumunda orijinal klasörde önemsemiyor o @InquilineKea tolds nedeniyle bu derste) orijinal dosyaları kaldırmak için vardır.

Tabii ki, eğer kaynak / ve hedef / klasörler farklı disklerde ise bu özellikle uygundur. Aksi takdirde, önerilen diğer çözümler daha verimlidir ( fileiçeriği yerine, adlandırma kurallarına bağlı olsalar bile ).


0

Bul ve mv'nin GNU sürümlerine sahip olduğunuzu varsayarak, aşağıdakiler mevcut bulmaya dayalı cevaplardan daha verimli olacaktır:

find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +

Bir Kullanarak +dosyaların bir listesini yerine dosyanın başına bir mv komutu idam etmekten, mv komutuna geçirilen olacağını bulmak -exec araçlarının sonunda buldum. Bununla birlikte, bunun bir sınırlaması sadece '{}' yi komutun sonuna yerleştirebilmenizdir, ki bu da mv --target-directory seçeneğinin kullanılmasını gerektiren ve bunun GNU-ism olduğunu bildiğim kadarıyla.

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.