Dosyaları nasıl bulabilirim ve sonra onları taşımak için xargs kullanabilirim?


28

Bazı dosyaları bulmak ve sonra onları taşımak istiyorum.

Dosyayı şurada bulabilirim:

$ find /tmp/ -ctime -1 -name x*

Onları ~/playdizine taşımayı denedim :

$ find /tmp/ -ctime -1 -name x* | xargs mv ~/play/

ama bu işe yaramadı. Açıkçası mv'nin iki argümana ihtiyacı var.
Mv komutundaki xargs 'current item' 'ine (ya da nasıl) başvuracağından emin değil misiniz?


3
Niye ya? Yer tutucuyu aşağıdakilerle birlikte kullanabilirsiniz -I: find . | xargs -I'{}' mv '{}' ~/play/ancak insanın dediği gibi, “İfade eder -xve ” dır -L 1. Yani kazanç yok. Daha iyi basit tutmak ve kullanmakfind . -exec mv '{}' ~/play/ \;
manatwork

Lütfen sakıncası yoksa oyları görmek için cevap olarak gönderiniz :)
Michael Durrant

Sadece sebebini istedim, hissettiğim gibi bir şey anlamadım. Drav Sloan, zımni seçeneklere not eklerse, cevabı yazabildiğim kadar iyi olacak. Öyleyse bununla git.
Manatwork


@ manatwork Cevabımı bu noktaları duder olarak yansıttım :)
Drav Sloan

Yanıtlar:


43

Stephane'nin en iyi yöntem için verdiği cevaba bakın, daha açık olan çözümleri kullanmama nedenleri (ve en verimli olmama nedenleri) için cevabımı inceleyin.

-ISeçeneğini kullanabilirsiniz xargs:

find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/

Hangi findve benzer bir mekanizma içinde çalışır {}. -nameArgümanınızı da alıntılardım (çünkü xmevcut dizinde başlayan bir dosya dosya globordur ve bulduğu argüman olarak geçer - beklenen davranışı vermez!).

Ancak, kılavuzda belirtildiği gibi, kılavuz xargssayfasında da belirtildiği gibi:

   -I replace-str
          Replace occurrences of replace-str in the initial-arguments with
          names read from standard input.  Also, unquoted  blanks  do  not
          terminate  input  items;  instead  the  separator is the newline
          character.  Implies -x and -L 1.

Unutulmaması gereken önemli şey , bir kerede -L 1yalnızca bir çıktı satırınınfind işleneceği anlamına gelir . Bu, sözdizimsel olarak aynı olduğu anlamına gelir:

find /tmp/ -ctime -1 -name "x*" -exec mv '{}' ~/play/

( her dosya mviçin tek bir işlem yürütür ).

GNU -0xargs argümanını kullanmak ve find -print0argüman aynı davranışa neden olur -I- bu clone()her dosya için bir işlemdir mv:

find . -name "x*" -print0 | strace xargs -0 -I '{}' mv '{}' /tmp/other

.
.
read(0, "./foobar1/xorgslsala11\0./foobar1"..., 4096) = 870
mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =     0x7fbb82fad000
open("/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26066, ...}) = 0
mmap(NULL, 26066, PROT_READ, MAP_SHARED, 3, 0) = 0x7fbb82fa6000
close(3)                                = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,         child_tidptr=0x7fbb835af9d0) = 661
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 661
--- SIGCHLD (Child exited) @ 0 (0) ---
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,         child_tidptr=0x7fbb835af9d0) = 662
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 662
--- SIGCHLD (Child exited) @ 0 (0) ---
.
.
.

Dosya adlarının yeni satır, tek tırnak, çift tırnak veya ters eğik çizgi içermediğini varsayar.
Stéphane Chazelas 16:13

17

GNU araçlarıyla:

find /tmp/ -ctime -1 -name 'x*' -print0 |
  xargs -r0 mv -t ~/play/

-t( --target) Seçenek GNU özeldir. -print0, -r, -0, GNU'da standart olmayan ve başlangıç bazı BSD olduğu gibi bazı başka uygulamalarda olarak bulunur.

POSIXly:

find /tmp/ -ctime -1 -name 'x*' -exec sh -c '
  exec mv "$@" ~/play/' sh {} +

Her ikisi mvde gerektiği kadar az komut çalıştırır ve dosya adlarının içerebileceği karakterleri kullanır. GNU , ilk toplu işlemi başlatırken finddosyaları aramaya devam eden bir avantaja sahip olabilir mv.

Tüm dosya ve dizinlerin bir dizinde sona ereceğine dikkat edin, farklı dizinlerdeki birkaç dosya aynı ada sahipse, çakışmalara dikkat edin.


Bu çözüm çok daha iyi o çağırır beri, performans mv(veya tümü için tüm argümanlar için bir kez -Lveya -ntedarik eğer). Aksi takdirde, mvher bir dosyayı aramak hızlı ve hızlı bir şekilde yaşlanacaktır.
r2evans

1

Belki bu komut şimdi mümkündür ve 2013'te geri gelmedi, ama bu benim için mükemmel çalışıyor:

ls pattern* | xargs mv -t DESTINATION/

-tSerbest bırakarak Hedef klasör ilk anahtar koyar, mvsadece dosyalar taşınacak olarak komutu tüm son argümanlar var.


1
Bu benim için çalışan en basit çözüm oldu
ptetteh227

0

Aşağıdaki komutu deneyebilir ve test edilmiş ve iyi çalıştı

find /tmp/ -ctime -1 -type f -name "x*" -exec mv -t ~/play/ {} \;
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.