Bir dizindeki tüm dosyaları bu dizine taşımak için Bash snippet'i


14

İçinde çok sayıda dosya ve dizin bulunan bir dizin var. Düzenlemek için, tüm bu dosyaları bir dizine koyacağım, bu yüzden böyle bir şey yapacaktım:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

O zaman hareket etmeye çalışacağım çünkü Ancak belli ki çalışmaz new_directoryiçine new_directory. Bu dizindeki tüm dosyaları ve dizinleri kopyalayıp yapıştırmak zorunda kalmadan tek bir satırda istediğimi yapmanın basit bir yolu var mı?


3
çalışır, sadece new_directory öğesini kendi kendine taşıyamayacağı bir hata mesajı yazdırır.
cas

Yanıtlar:


18

Sizin

mv * ./new_directory
komut aslında işe yarayacak; sadece bu dizini kendine taşıyamayacağına dair bir uyarı yazdırır.


Bununla ilgili 'tek' sorun, komutun toplam genişletmesi çok uzun olursa (yani çok fazla dosya, çok uzun ad) artık çalışmaz.
Niels Basjes

Yan not olarak, bunu bir ile git mvyapacaksanız, -kbayrağı kullanmanız gerekir , çünkü git varsayılan olarak başarısız olur, sadece bir uyarı vermez. Yani yapmanız gerekecek git mv -k * ./new_dir.
Yuval A

11

Hızlı ve kirli bir oneliner.

mv `ls -A | grep -v new_directory` ./new_directory

1
Çalışmaz: Düz ls nokta dosyaları göstermez.
wzzrd

Çok iyi bir nokta. Bir -a ile düzeltildi.

2
Yani yeni_dizini kendine mv denemeye çalışmak yerine (Orijinal soru) şimdi hareket etmeye çalışıyorsun. ve .. yeni_dizine.
Niels Basjes

2
Geri bildiriminiz için teşekkürler Niels. Bunu kaldıran bir üst a ile düzeltildi. ve .. dizin listesinden.

8

Sadece dosyaları arıyorsanız (yani dizinleri değil),

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

en taşınabilir çözümdür. Hız için, find ve xargs öğelerini -print0 ve -0 ile taşımalısınız, ancak yalnızca GNU find ve xargs varsa.


3
Oldukça yeni bir GNU bulgusu kullanarak \ yerine \ + da kullanabilirsiniz; yaptığımız mv sayısını azaltmak için.
wzzrd

GNU bulmanız varsa, aynı şeyi yapacak xargs da kullanabilirsiniz ve -p bayrağıyla aynı anda birden fazla mvs çalıştırmanıza izin verirsiniz.
Cian

serin kullanımı find- ne yazık ki kesinlikle bir tane olmayan sistemlerde oldum, ne yazık ki :(
warren

Gerçekten mi? find (afaik) SUS'ta belirtilir, bu yüzden her şeye sahip olmalıdır. Tek sorun, GNU bulması (çok güzel serin seçeneklere sahip) veya düzenli bulmasıdır.
Cian


6

Bu sorunu yaşadığım zamanlarda aşağıdakilerden birini yaptım:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

veya

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

İkinci form, '.' İle başlayan joker karakter atlama dosya adlarından yararlanır.


Joker kartı atlanan noktalı dosyaları unuttum; hatırlatma için teşekkürler ! :)
aemonge

2

ne dersin:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

IOW, içeriği yeni bir dizine taşımayın, ancak bu dizini yeni bir dizinin içine koyun.


1

@ Rembrane'nin cevabına benzer şekilde (tek astar olmasa da):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

findSisteminizde ne yazık ki olmasa bile, bu % 100 taşınabilir olmalıdır .


find, tekli unix spesifikasyonunda gereklidir. Bu nedenle, asla olmamalı (bununla bir şey inşa edemeyeceğinizden değil. Ama korkunç bir çaba gerektireceğini hayal ediyorum ve hiçbir satıcı sistemi eksik olmayacak)
Cian

belki bazı hiper paranoyak sysadmin yoinking findutils veya eşdeğeri? emin değilim, ama ben onu olmayan boxen içine koşmak biliyorum :(
warren

1

Önerilerim: Başkaları tarafından belirtildiği gibi,

mv * ./new_directory

IFF bulmaya çalışacak toplam genişleme yeterince kısa.

Diğer akıllıca çok daha fazla sayıda dosyaya ölçeklenen bunu deneyebilirsiniz:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

açıklama

  1. Tüm dosyaları listele.
  2. Tüm dosya adlarını maksimum 100000 karakterlik parçalar halinde gruplayın.
  3. Parça başına tek bir mv komutu oluşturun.

dosya adlarınızda boşluk varsa kırılır
Cian

Haklısın. Bu yüzden bunu düzeltmek için -print0 ve -0 bayrakları ile artırılmalıdır.
Niels Basjes

Birlikte denedim -print0ve -0ve hala sonları.
Cristian Ciupitu

find: warning: seçenek olmayan bir argüman olan -type öğesinden sonra -maxdepth seçeneğini belirttiniz, ancak seçenekler konumsal değil (-maxdepth, kendisinden önce belirtilen ve sonrasında belirtilen testleri etkiler). Lütfen seçenekleri diğer argümanlardan önce belirtin.
Cristian Ciupitu

1

kullanın:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

Gönderen xargsadam sayfası:

-P max-procs

  Run up to max-procs processes at a time;

-1

Hata mesajını önlemek ve basit tutmak için:

mv *.* ./new_Folder

aynı şeyi yapacak ama hata mesajından kaçının (klasör adlarınızda noktalar yoksa sanırım).

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.