İki tarih arasındaki dosyaları “find” kullanarak nasıl bulabilirim?


21

60GB e-postaları geçen bir e-posta hesabım var ve şu anda geçen yılın e-postalarını arşivlemek için bir e-posta istemcisi kullanmakta büyük sıkıntı yaşıyorum (2011).

Terminal üzerinden, 2011-01-01 ve 2011-12-31 arasında dosyaları bulmak için find kullanmaya çalışıyorum , ancak boşuna yok.

İki tarih arasındaki dosyaları nasıl bulabilirim?

Gerekirse, son hedef, tarih aralığına uygun olarak bulunan her dosyayı bir klasöre taşıyacak bir toplu iş olacaktır.


@EliahKagan Bellek hizmet ederse, çoğaltılmış isimler bir sorun değildi. Bununla birlikte, zamanınız olduğunu bildirirseniz, herhangi bir konuda ek bilgi her zaman takdir edilir :) Ayrıca, bu konuda daha fazla bilgi sağladığı için cevabınızı artırdım.
Zuul

@EliahKagan Bu durumda, vurguladığınız pratik arızaya karşı güvenli bir cevap vermenizi tavsiye ederim :)
Zuul

Yanıtlar:


16

Bu betiği kullanabilirsiniz:

#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
  mv $i /moved_emails_dir/
done

6
Çıktısı, findböyle bir kabuk fordöngüsünde işlenmemelidir , ancak hiçbir dosyanın adında boş boşluk bulunmadığı garanti edilmediği sürece. -exec, -execdirveya -print0 | xargsbunun yerine genellikle kullanılmalıdır; Genellikle daha az arzu edilen ancak bir fordöngünün kullanılmasına izin veren başka bir olası çözüm, IFSbir alanın bir alan ayırıcı olarak tanınmaması için geçici olarak ayarlanır .
Eliah Kagan

@EliahKagan öyleyse komut neye benzeyecekti: yerine findsadece exec? Boşluk kullanımına cevap veren bir cevap ekler misiniz? Çok takdir.
SherylHohman

3
@SherylHohman Hayır, execkomutu kullanmayın . Gönderdiğim yanıtta açıklandığı şekilde, çalıştırılacak eylemle veya çalıştırmanız gereken her şeyi findiçeren bir komut kullanın . Ne zaman ... o buldu yol adlarının ile komutu çalıştırır alanlarda tetiklemek kalmamak, o bir kabuk kullanmaz kelime bölme veya globbing . (Özel durumunuz hakkında yeni bir soru göndermek veya tam olarak ne bilmek istediğinizi sormak isteyebilirsiniz.)-execmvfind-exec
Eliah Kagan

@EliahKagan Üzgünüz, gönderinizi yanlış okudum - sizden ! Harikasın! Gönderiniz Mükemmel .. ve okumadaki kendi hatam olmasına rağmen yanıt verdiğiniz için teşekkürler !!
SherylHohman

40

Bash iki tarih arasındaki dosyaları bulur:

find . -type f -newermt 2010-10-07 ! -newermt 2014-10-08

2010-10-07'den sonra ve 2014-10-08'den önce zaman damgası olan dosyaların bir listesini döndürür

Bash 15 dakika öncesine kadar dosyaları buluyor:

find . -type f -mmin -15

15 dakika önce ancak şimdiden önce zaman damgası olan dosyaların bir listesini döndürür.

Bash iki zaman damgası arasında dosya bulur:

find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"

2014-10-08 10:17:00Ve arasındaki zaman damgalarına sahip dosyaları döndürür2014-10-08 10:53:00


10

Dosyaları taşımak ve kullanıcıdan yinelenen adlar olup olmadığını sormak:

As Subv3rsion en ve Eric Leschinski en cevapları göstermek, -newermtyüklem seçer dosyalar kendi işlenen olarak belirtilen tarih (ve isteğe bağlı saat) daha son değiştirilen. Dosyaları bulmak

  • herhangi bir yerde srcdir(yani, alt dizinleri, alt dizinleri vb. dahil)
  • en son değiştirilme tarihi (örneğin) Eylül 2014
  • ve taşımak içindestdir

...koşabilirsin:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;

Bir -execifadede, find yerine bulunan dosya adını iletir {}. Çalıştırılacak komutun ve argümanlarının hepsinin sağlanmış olduğunu ;belirtir -exec(sonraki ifadelerin, bu belirli -execyüklemenin argümanlarından sonra bulmak için geçmesi durumunda - bunun için aşağıya bakınız). ;kaçması gerekir, \;bu yüzden kabuk tarafından özel olarak yorumlanmamıştır. (Olmadan \, ;tüm findkomutu sonlandıracak, yeni bir satırla aynı şekilde çalışacak. Bu findkomutun bu -execifadeden sonra hiçbir şeyi olmamasına rağmen , ;argümanı geçememek yine de sözdizimi hatasıdır.)

Dosyaları yalnızca listelemek istiyorsanız - eski e-postaların nasıl depolandığından veya başka hangi dosyaların mevcut olabileceğinden emin değilseniz önerilir - atlar -execve her şey için bu hakkı sağlayın . (E-posta için, genellikle farklı tarihlerden gelen e-postalar aynı dosyada saklanır ; burada sorulan durumda olan biri için, herhangi bir dosyayı taşımadan önce nasıl depolandıklarını araştırmanızı öneririm.) Hem adlarını yazdırmak hem de taşımak onları daha -printönce ekleyin -exec.

mv -i Bir dosyanın hedefe yazılacağı herhangi bir zamanda sorulur, örneğin:

  • aynı adda bir dosya önceki bir yedekten var veya
  • aynı adda ancak farklı bir alt dizininden bir dosya srcdiraynı findişlem sırasında çoktan taşındı veya
  • (en azından muhtemel) aynı adda bir dosya srcdir, aynı findişlem sırasında , orijinaller taşındıktan sonra, ancak findbir zamanlar farklı bir alt dizine geçtiğinde, yeterince kısa sürede bulunacak bir yerde yaratıldı .

Çağırmanın diğer yolları rm:

Çift isimleri olan dosyaların nasıl kullanılacağı konusunda başka seçenekleriniz de var.

  • Olmadan -i(yani ), genellikle onay istenmez, ancak hedef dosya salt okunur olsaydı bunu yapardı. ( bazen dosyayı çalıştıran kullanıcı gibi) salt okunur bir dosyanın üzerine yazmayı bile başarabilir.)mv {} destdir/mvmv
  • Bu derecede bir etkileşim derecesi istemiyorsanız ve mvher zaman aynı adlandırılmış dosyaların üzerine yazmak (denemek) istiyorsanız , kullanın mv -f.
  • Buna karşılık, aynı adı taşıyan bir hedef dosya zaten varsa, kaynak dosyaları atlamak istiyorsanız, kullanın mv -n.
  • mvHedefte zaten var olan özdeş adları taşıyan dosyaları otomatik olarak yeniden adlandırmak için -bve --backupbayrakları kabul eder . ~Yedekleme adını üretmek için varsayılan olarak eklenir ve hedefte adın bulunduğu bir dosya ve yedek adının bulunduğu bir dosya varsa, yedekleme dosyasının üzerine yazılır. Bu varsayılan, çağrılırken geçirilen seçeneklerle mvve ortam değişkenleriyle geçersiz kılınabilir . Ayrıntılar man mvve aşağıdaki örneğe bakın.

Tekrarlanan adlar durumunda dosyaları taşıma ve yedeklemeler oluşturma:

Tüm dosyaları taşımak, dosyaları bir ~sonek kullanarak yinelenen adlarla yedekleyin ve dosyalar zaten varsa (herhangi bir şeyin üzerine yazılmasını önlemek için) numaralı sonekleri kullanın..~n~.~

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;

Dosyaları yinelenen adlarla atladıysanız ve hangilerinin olduğunu bilmek istiyorsanız:

Eğer kullanırsanız mv -nve aynı adla başka bir dosya olduğu için taşınmaz hangi dosyaların bilmek istiyorum, en iyi yolu sadece orijinal çalıştırmak için muhtemelen findolmadan tekrar komutu -execsağında ve herşey. Bu isimlerini yazdıracak.
Ayrıca, orijinal find .... -exec ...komutu çalıştırdığınızdan beri oluşturulan tüm eşleşen dosyaların adlarını da yazdıracaktır , ancak bu uygulama için eski değişiklik zamanları olan dosyaları aradığınızdan genellikle hiçbiri olmayacaktır. Bir dosyaya, gerçek yaşından daha eski bir değişiklik zaman damgası touchve diğer mekanizmaları vermek mümkündür , ancak bu durumda bilginiz olmadan gerçekleşmesi muhtemel görünmemektedir.

Çift isimler nedeniyle dosyaların hemen atlandığını bilmek:

mv -nBir dosyayı taşımaktan kaçındığında, herhangi bir özel çıkış kodunu rapor etmez veya geri göndermez . Bu nedenle, findçalıştırılırken atlanan dosyalar hakkında derhal haberdar olmak istiyorsanız, bunun için ayrı bir adım atmanız gerekir. Bir yol:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
    -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \; 

Muhtemelen küçük teknik hususlar: mvBir dosyayı hedefte var olandan farklı bir nedenden kopyalayamazsa ve raporlama başarısından çıkarsa bu yanlış uyarı verir . Bu mümkün görünmüyor, ancak imkansız olduğundan emin değilim. Aynı zamanda potansiyel olarak bir yarış koşuluna da maruz kalır: eski bir dosya taşındıktan kısa bir süre sonra aynı yerde ve aynı zamanda kontrol edilmeden önce aynı yerde yeni bir dosya oluşturulursa, gerçek bir hata olmadığı zaman uyarılır. bakalım çıkarılmış mı. (Uygulamayı göz önünde bulundurarak, herhangi bir sorunun gerçekten ortaya çıkacağından şüpheliyim.) Daha önce hedefi kontrol etmek için yeniden yazılabilirdi.dosyayı sonra yerine taşımak: daha sonra yarış durumu kaynak dosyalar yerine yeni oluşturulan hedef dosyalarla ilgilidir. Ve findveya mv(veya [olmamasına rağmen) bildirilen hatalar ve uyarılar standart hataya yazılırken , ...skipped (exists in...uyarımız standart çıktıya yazılır . Normalde her ikisi de terminalinizde görünür, ancak komut dosyası kullanıyorsanız bu önemli olabilir.

Daha kolay okumak için bu komutu iki satıra böldüm. Bu şekilde çalıştırılabilir veya \yeni çizgiyi (yani satır sonu) kaldırabilirsiniz .

Bu findkomut nasıl çalışıyor?

findTahminler, geri dönüş değerleri için kullanılan testler (gibi -typeve -newermt) veya genellikle yan etkileri için kullanılan eylemler (gibi -printve -exec) olabilir.

Hiçbir (gibi operatör zaman -aiçin ve , -oiçin ya ) ifadeleri arasındaki beslenir, -aima edilir. ve ve veya için kısa devre değerlendirmesifind uygular . (yani, ) yalnızca p ve q ifadelerinin her ikisi de doğruysa doğrudur, bu nedenle p'nin yanlış olması durumunda q değerlendirilmesine gerek yoktur . Sık sık bu terimlerle düşünmemize rağmen, testlerin sonraki eylemler veya değerlendirilecek testler için doğru olmasının nedeni budur. Örneğin, bir dizinin üstüne geldiğini varsayalım . False olarak değerlendirir , böylece daha sonra her şeyi atlayabilir.p qp -a qfind-type f

Testler gibi, eylemler de doğru veya yanlış olarak değerlendirilir. Bu şekilde, -execyürütülen komutun raporlama başarısından (doğru) veya başarısızlıktan (yanlış) çıkıp çıkmadığını bildirir. Biz bu zinciri var -execörtük ile bağlı ifadeler ve :

-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;

Bu dosyayı taşımaya çalışır ve eğer mvrapor başarısız olursa durur. Başka bir sorun neden taşınmamışsa, doğru atlanmış bir dosya hakkında uyarmak istemiyoruz.

Fakat başarılı olursa , [komutu çalıştırır . Mesela find, [argüman olarak iletilen kendi ifadelerini destekler. [ -f {} ]Sonrasında işlenenin -f(onun findyerine geçtiği yer {}) var olup olmadığını denetler (ve normal bir dosyadır) ve doğru / başarı ya da yanlış / başarısızlık döndürür.
(Pek çok komutun çıkış durumları en iyi başarı veya başarısızlık anlamına gelir olarak yorumlanır, ancak [var olan durumu genellikle en iyi şekilde doğru veya yanlış olarak yorumlanır.)

Eğer [yanlış döndü ardından dosya o taşındı bu yüzden, bu yüzden herhangi bir şey yapmaya gerek yoktur, gitti. Ancak [false döndürülürse, dosya hala oradadır. Ardından , uyarı mesajını basan bir findsonraki -execifadeyi değerlendirir .

Daha fazla okuma


Zamanım döndüğümde, performans konuları hakkında ve bir bölüm eklemek için umut -exec ... +ile mv -tbazen yakında.
Eliah Kagan
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.