Dosyaları Yıla göre taşıma


15

Dosyaları bir yıla göre taşımam gerekiyor. findKomutu kullandım

find /media/WD/backup/osool/olddata/ -mtime +470 -exec ls -lrth {} \;|sort -k6

ancak bu komutun başarılı bir şekilde yürütülmesi için tam mtimeolarak 470'in sadece bir tahmin olduğunu bilmem gerekiyor . 2012 yılını verebilirsem bana sadece 2012 ile ilgili dosyalar verir.

Bu yüzden nasıl yapılacağı konusunda tavsiyeye ihtiyacım var

Dosyaları 2012 yılına göre bulun ve başka bir dizine taşıyın.

OS release 5.2

FIND version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX 

-exec ls ... \;Bunun yerine kullanmak mantıklı mı -exec ... +? Bulmanız bunun için çok mu eski? Bu durumda find ... -print0 | xargs -0 ls...çok daha hızlı olurdu.
Hauke ​​Laging

Coreutils ile ilgili bu soruların (ve cevapların) rutin olarak GNU veya BSD (veya diğer) araçlarla ilgilenip ilgilenmediğimizi belirtmesini isterdim.
labirent

Yanıtlar:


39

-newermtSeçeneği aşağıdakiler için kullanmak istiyorsunuz find:

find /media/WD/backup/osool/olddata/ -newermt 20120101 -not -newermt 20130101

2012 yılında değişiklik zamanı ile tüm dosyaları almak için.

Bulmanız desteklemiyorsa -newermt, ofset hesaplamalarının kullanılmasını önlemek için aşağıdakileri de yapabilirsiniz:

touch -d 20120101 /var/tmp/2012.ref
touch -d 20130101 /var/tmp/2013.ref
find /media/WD/backup/osool/olddata/ -newer /var/tmp/2012.ref -not -newer /var/tmp/2013.ref

1
-newermt bayrağı Bul komutunda kullanılamıyor
OmiPenguin

Bu, RHEL'inizle birlikte gelen eski bir sürüm mü olmalı? Bunun cevabında bir alternatif sunacağım
Anthon

Evet bu bir 5.2
OmiPenguin

RHEL'in revizyonu olduğunu düşünüyorum, değil find(4.4.2 sürümünü buldum)
Anthon

1
Newermt anahtarı v4.3.3, gnu.org/software/findutils/manual/html_mono/find.html sürümünden sonraki sürümlere kadar aramada görünmedi .
slm

5
touch --date=2011-12-31T23:59:59 start
touch --date=2012-12-31T23:59:59 stop
find / -newer start \! -newer stop -printf %Tx" "%p\\n

-exec ls hiç mantıklı değil.


1
-exec ls -ltest ederken daha mantıklı ve hatta daha fazla.
CVn

@ MichaelKjörling findmümkün olan her şeyi yazdırabilir ls. Tamam, bir istisna dışında: hoş olmayan karakterlerden kaçma / alıntı yapma. Ancak genel olarak çıktısı finddoğrudan sıralanabilir. Yararsız ls çağrıları her şeyi daha hızlı yapmaz.
Hauke ​​Laging

Test ederken çok benzer bir şey kullanıyorum (kişisel olarak tercih etsem -printveya muhtemelen de olsa -ls ). Kullanmanın avantajı, -exec ls {}zaten bulmak için harici bir şey yürütmesidir . Eğer geçiş Böylece zaman lsiçin mv, gerçek değişiklikler çok az.
bir CVn

3

Man sayfasına göre, -mtime argümanı aradığınız gün sayısıdır. Bu date +%jyılın 1 Ocak tarihinden bu yana geçen gün sayısını bulmak için kullanabilirsiniz .


2
İyi yol. Çok "nitpicky" olmak: -mtime -1: son 24 saat içinde herhangi bir dosyadır. Sadece dünden (veya bugün) gelen dosyalar değil. Yani, küçük bir "çakışma" da olacaktır: 2012'den bu yana 120 gün geçtiğini belirlerseniz ve bugün komut dosyasını başlattığınızda 15:45 olur, 31 Aralık 15:45'e kadar olan dosyaları seçersiniz ( ve o günün sonuncusunu değil) ... Muhtemelen şunu kullanabilirsiniz: nb_day - 1 ve sonra 2013'ten itibaren birkaç tane "ayıkla" (bunlar bir ls -l | grep -v, AMA tarafından bulunabilir) sadece 1 günlük olmaları durumunda çıktı farklıdır ... çok sayıda tuzak ...)
Olivier Dulac

Çalışacaksanız -daystartseçeneği kullanmak istersiniz -mtime. Aksi takdirde, tam olarak gece yarısında çalıştırmazsanız, yılın başında ve sonunda dosyalarda sorun yaşarsınız. Sen yapabilirsin daha doğru ile offset -mminile daha -mtimeyeni yıl kolayca beri dakika sayısını bulabilirseniz. Ancak, aynı sorun -mtime, daha az dosya için (gece yarısı gece yarısı civarında olanlar) olduğu gibi.
Anthon

1
Evet, man sayfasını tekrar okuyorum Bunu nasıl saatler sürdüğünü görüyorum, bu yüzden basit bir işlem yapmak find -mtime $("date -+%j")muhtemelen OP'ye ne istediklerini vermeyecek. Bunu gelecek nesiller için bırakıyorum, çünkü bu insanların içine düşmesi olası bir kör nokta gibi görünüyor.
Bratchley

2

Aşağıdaki tek satırlardaki gibi statve / veya datekomutlarıyla bir kombinasyon kullanmayı deneyebilirsiniz :

BSD / Mac OS X:

find . -type f -print | while read file; do eval `stat -s "$file"`; year=`date -jf "%s" "+%Y" "$st_mtime"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

Linux:

find . -type f -print | while read file; do year=`date -r "$file" "+%Y"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

Her iki durumda da yaklaşım, dateher dosyanın son değiştirme zamanından yılı ayıklamak ve daha sonra bu yılla bir yol oluşturmak için komutu kullanmaktır . Komut mkdir -pzaten yoksa bu yolu oluşturur. Elbette findaramanızı daraltmak için başka seçenekler de kullanabilirsiniz .


1

Bunu çalışma dizininden yaparsanız, bunun yerine bunu yapabilirsiniz:

ls -l |awk '{ if ($8 == "2013") print $9 }'

Bu, işleri önemli ölçüde basitleştirir ve çakışmalara neden olmaz. Ancak, bu dosyaların 6 aydan eski olduğunu lsve tam zamanı yerine yılı yazdıracağını da varsayar .

6 aydan daha eski dosyalar için, bunu bununla değiştirmeniz yeterlidir:

ls -l |awk '{ if ($6 == "May") print $9 }' 

veya aya bağlı olarak benzer bir şey. Dosyaları taşımak için ayların bir listesini oluşturmak istiyorsanız (veya yıllarca bir liste oluşturmak istiyorsanız) bunu yapın:

month="May Jun Jul"; 
for i in `echo $month`; 
do 
    for j in `ls -l |awk '{ if ($6 == "'$i'") print $9}'`
    do
        mkdir -p $i
        mv $j $i
    done
done
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.