Find komutundan sonra mv komutu nasıl entegre edilir?


61

AAAAşağıdaki komutu kullanarak kendi yolunda adı olan dosyaları arıyorum :

find path_A -name "*AAA*"

Yukarıdaki komutun gösterdiği çıktı göz önüne alındığında, bu dosyaları başka bir yola taşımak istiyorum path_B. Bu dosyayı birer birer taşımak yerine, bu dosyaları find komutundan hemen sonra taşıyarak komutu optimize edebilir miyim?

Yanıtlar:


87

GNU mv ile :

find path_A -name '*AAA*' -exec mv -t path_B {} +

Bu, sırasıyla her bir bulma sonucunun -execyerine geçen {}ve verdiğiniz komutu çalıştıran bulma seçeneğini kullanır . Açıklandığı gibi man find:

   -exec command ;
          Execute  command;  true  if 0 status is returned.  All following
          arguments to find are taken to be arguments to the command until
          an  argument  consisting of `;' is encountered.  

Bu durumda, mümkün olan en az işlemi çalıştırmak için +sürümünü kullanıyoruz :-execmv

   -exec command {} +
          This  variant  of the -exec action runs the specified command on
          the selected files, but the command line is built  by  appending
          each  selected file name at the end; the total number of invoca‐
          tions of the command will  be  much  less  than  the  number  of
          matched  files.   The command line is built in much the same way
          that xargs builds its command lines.  Only one instance of  `{}'
          is  allowed  within the command.  The command is executed in the
          starting directory.

"\;" Yi unutma exec sonunda!
Charles Roth

@Charles Roth: +İşi yapan şey, yukarıdaki veya man findbunun yerine
alıntımı

Bunun için teşekkürler! Kullanmaya çalışıyordum -exec mv {} path_b +ve izin hatalarıyla başarısız oluyordu. TBH, nedenini hala anlamadım, ama iyi -exec mv -t path_b {} +davranıyor!
Jeremy Davis,

6
@JeremyDavis Kullanırken -exec ... {} +, {}önceki son şey olmalı +. Bu yüzden kullanır mv -t destdir {} +ve kullanmaz mv {} destdir +. Bunun -exec mv {} destdir ';'yerine bir soğuk kullandı , ancak bu mvher dosya için bir kez yürütüldü .
Kusalananda

23

Aşağıdakine benzer bir şey yapabilirsin.

find path_A -name "*AAA*" -print0 | xargs -0 -I {} mv {} path_B

Nerede,

  1. -0Boşluk veya karakter varsa (yeni satırlar dahil) birçok komut çalışmaz. Bu seçenek boş alan içeren dosya adlarına özen gösterir.
  2. -IAlternate-str oluşumunu ilk argümanlarda standart girdiden okunan isimlerle değiştirin. Ayrıca, işaretlenmemiş boşluklar girdi öğelerini sonlandırmaz; bunun yerine ayırıcı yeni satır karakteridir.

Test yapmak

Ben iki dizin yarattı sourcedirve destdir. Şimdi, içindeki dosyaların vazo üreterek sourcedirolarak file1.bak, file2.bakvefile3 with spaces.bak

Şimdi emri yerine getirdim.

find . -name "*.bak" -print0 | xargs -0 -I {} mv {} /destdir/

Şimdi, içeride destdirbulduğumda, lsben dosyaları taşınmış olduğunu görebiliyordu sourcediriçin destdir.

Referanslar

http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/


22

Bu soruyla karşılaşan OS X kullanıcılarının yararı için, OS X'teki sözdizimi biraz farklıdır. Alt dizinlerinde özyinelemeli olarak arama yapmak istemediğinizi varsayalım path_A:

find path_A -maxdepth 1 -name "*AAA*" -exec mv {} path_B \;

Tüm dosyaları yinelemeli olarak aramak istiyorsanız path_A:

find path_A -name "*AAA*" -exec mv {} path_B \;

Bu, OS X'e özgü bir sözdizimi değildir, kullandığımla aynı find. İyi noktalar: -maxdepth(eğer yol_B bir alt dizinse espeically - mvdosyaları zaten oraya taşımaya çalışmaktan kaçınır !) Ve \; (yani {} son parametre olmak zorunda değildir ve normal mvsözdizimi kullanılabilir)
drevicko

6

Bunu -execyapmanın en iyi yolu budur. Herhangi bir nedenden ötürü, bu bir seçenek değilse, sonuçları bir döngü halinde de okuyabilirsiniz:

find path_A -name "*AAA*" -print0 | 
    while IFS= read -r -d $'\0' file; do mv "$file" path_B; done

Bu güvenli bir yoldur, boşluk, yeni satır veya başka garip karakterler içeren dosya adlarıyla başa çıkabilir. Daha basit bir yol, ancak dosya adlarınız yalnızca basit alfasayısal karakterlerden oluşmadıkça başarısız olan,

mv $(find path_A -name "*AAA*") path_B

Ancak while döngüsünü kullanın.


your file names consist only of simple alphanumeric charactersÖrneğin, eğer ulaşıyorsa, daha basit bir yol hala başarısız olabilirARG_MAX


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.