Belirli bir zaman aralığında değiştirilen dosyalar nasıl listelenir?


38

22.12.2011 ve 24.12.2011 tarihleri ​​arasında değiştirilen tüm dosyaları tekrarlı olarak nasıl listeleyebilirim?


6
Eğer 'son değişiklik' demek istiyorsan, bir çözüm bulma şansın var. 26.12.2011 tarihinde bir dosya değiştirilmişse, verilen aralıkta da değiştirilip değiştirilmediğini söyleyemezsiniz. (Çok egzotik bir dosya sisteminiz yoksa.)
William Pursell

Yanıtlar:


25

Genel olarak konuşursak, bir dizindeki dosyaları ve alt dizinlerini tekrar tekrar ararken, kullanın find.

Bir tarih aralığı belirtmenin en kolay yolu find, aralığın sınırlarında dosya oluşturmak ve -neweryüklemeyi kullanmaktır .

touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop

neden ilk çıktıyı olumsuzlamak -newerburada gerekli?
Alexander Cska,

@AlexanderCska Birincisi -newerolumsuz değil, ikincisi. “Yeni olan startancak yeni olmayan dosyaları bulun stop”.
Gilles 'SO- kötülük'

Tamam olumsuzlama sonra komutunda çalışır. Herhangi bir olumsuzlama olmasaydı ne olurdu?
Alexander Cska,

@AlexanderCska Sonra ikisi daha yeni olan dosyaları elde ediyorum startve stop.
Gilles 'SO- kötülük' dur

35

Gilles'un çözümünü kullanarak adam bulduktan sonra (1) tekrar bulup daha basit bir çözüm buldum. En iyi seçenek -newerXY'dir. M ve t bayrakları kullanılabilir.

m   The modification time of the file reference
t   reference is interpreted directly as a time

Yani çözüm

find . -type f -newermt 20111222 \! -newermt 20111225

Kapsayıcı dahil alt sınır ve üst sınır özeldir, ben de ona 1 gün ekledim! Ve özyinelemeli. Bu v4.5.9 bulmak üzerinde iyi çalışıyor.


Harika numara, teşekkürler! Bu, binlerce dosya içeren bir dizinde belirli bir anahtar kelimeyi içeren yeni bir dosya bulmada bana yardımcı oldu: find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l( -m 50= ilk 50 satırda arama yap).
Rob W

@RobW: Aslında kullandığınız boru ve xargs ayırabilirim -exec ... +içinde find(1)gibi: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +. Bu aynı, ancak daha ucuz.
TrueY

Zaman damgalarını çift tırnak içine almak zorunda kaldım (Ubuntu Xenial ile beraberim find 4.7.0-git).
IsaacS

13

Daha önce verilen cevaplara ek olarak, tarihlerinizi doğrudan belirleyebileceğinizi unutmayın:

find -type f -newermt "2011-12-22" \! -newermt "2011-12-24"

veya

find -type f -newermt "2011-12-22 00:00:00" \! -newermt "2011-12-24 13:23:00"

ek olarak saati belirtmek istiyorsanız.


6

Saniyede hassasiyete ihtiyacınız olmadığını varsayalım, bu çalışması gerekir.

find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))

DÜZENLEME: Değiştirilen cminiçin mminEelvex yorumuna @ sonra. EDIT: '\!' eksik


hm işe görünmüyor. alt dizinleri yinelemeli olarak geçtiğinden emin misin?
kelepçe

Evet, bende işe yarıyor. Gerçekten o zaman aralığında değiştirilmiş dosyalarınız var mı? Farklı zaman aralıklarında deneyin.
onur güngör

6
-cmin"durum değişikliği", -mmin"veri değişikliği" dir. Muhtemelen istiyorsun-mmin
Eelvex

3

findtarih olarak ISO biçimli bir zaman alabilir; bu nedenle, örneğin UTC'deki bir sunucu için, nerede olursanız olun, birkaç saatlik bir kayma belirtebilirsiniz. Bu aynı zamanda zamanı karşılaştırdığınızdan beri bir gün eklemek zorunda kalmanıza da dikkat eder:

find -type f -newermt 20111224T0800 \! -newermt 20111225T0800

0

Lütfen yinelenen olarak işaretlenen ve bu nedenle doğrudan yanıtlamaktan sınırlandırılan sorunun, buraya neden gönderiyorum olduğunu lütfen unutmayın. Bu cevap, "dosyaları [oluşturma] tarihine göre farklı bir klasöre taşımanız gerekir" sorusunu yanıtlamak içindir.

Cevaplar makul, ancak tamamen bulun komutuyla bazı sınırlamalar vardı. Bu kabuk betiğini, içinde o kadar çok dosya bulunan bir dizinde ilerlemek için dosya sisteminde bir ls gerçekleştirmeye çalışan meta veride tıkaçlar olduğunu yazdım. Ek olarak, bazı * nix sistemleri, ls çalıştırmada çok fazla sayıda argüman hatası ortaya çıkaracaktır.

Find komutu çok güçlü ve listelenen yöntemlerle başladım, ancak bu dizinde yıllarca veriye sahip oldum, tüm dosyaları tekrar tekrar geçmek zorunda kaldım. Bu, her dosya için çok fazla gereksiz yere geçmeye neden olur. Yılda bir ekran yapmayı ve birden fazla bulmayı çalıştırmayı denedim, ancak bu her bulgunun üzerinde çok fazla hataya neden oldu ve buluntulardan biri taşındığında dosyalar kayboluyordu.

Shell betiğim, bir dosyayı 4 basamaklı bir yıl ve 2 basamaklı bir ay ile hedef dizine taşır. Birkaç çizgiyi sıkıştırarak ve meslektaşlarına yorum yaparak kolayca 2 basamaklı bir güne genişletilebilir. Bunun daha verimli olduğuna inanıyorum çünkü hamle bir seferinde find komutunu gerçekleştirdi, bu yüzden çoklu bulma komutları ve dizin üzerinden geçişler gereksiz.

#!/bin/bash
#We want to exit if there is no argument submitted
if [ -z "$1" ]
then
  echo no input file
  exit
fi

#destDir should be set to where ever you want the files to go
destDir="/home/user/destination"

#Get the month and year of modification time
#--format %y returns the modification date in the format:
# 2016-04-26 12:40:48.000000000 -0400
#We then take the first column, split by a white space with awk
date=`stat "$1" --format %y | awk '{ print $1 }'`

#This sets the year variable to the first column split on a - with awk
year=`echo $date | awk -F\- '{print $1 }'`
#This sets the month variable to the second column split on a - with awk
month=`echo $date | awk -F\- '{print $2 }'`
#This sets the day variable to the third column split on a - with awk
#This is commented out because I didn't want to add day to mine
#day=`echo $date | awk -F\- '{print $3 }'`

#Here we check if the destination directory with year and month exist
#If not then we want to create it with -p so the parent is created if
# it doesn't already exist
if [ ! -d $destDir/$year/$month ]
then
  mkdir -p $destDir/$year/$month || exit
fi

#This is the same as above but utilizes the day subdirectory
#Uncommented this out and comment out the similar code above
#if [ ! -d $destDir/$year/$month/$day ]
#then
#  mkdir -p $destDir/$year/$month$day || exit
#fi

#Echoing out what we're doing
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
echo Moving $1 to $destDir/$year/$month
#echo Moving $1 to $destDir/$year/$month/$day

#Move the file to the newly created directory
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
mv "$1" $destDir/$year/$month
#mv "$1" $destDir/$year/$month/$day

Bir kere kaydedildikten ve çalıştırılabilir olduktan sonra, aşağıdaki betiği bulmak için bu betiği çağırabilirsiniz.

find /path/to/directory -type f -exec /home/username/move_files.sh {} \;

Bulmak için newermt seçeneğini ayarlama konusunda endişelenmenize gerek yoktur, çünkü tüm buluntular, bulunan her dosya için tek bir yürütmedir ve komut dosyası tüm kararları verir.

-Tipini seçmezseniz, dizinleri dolaştıracağını ve muhtemelen sorunlara yol açabileceğini unutmayın. Yalnızca dizinleri taşımak istiyorsanız -type d de kullanabilirsiniz. Türü ayarlamamak neredeyse kesinlikle istenmeyen davranışlara neden olacaktır.

Unutma ki bu senaryo benim ihtiyaçlarıma dayandı . Yapımımı, ihtiyaç betiğinize daha iyi uyması için ilham kaynağı olarak kullanmak isteyebilirsiniz. Teşekkür ederim!

Dikkat Edilmesi Gereken Noktalar: Komutun etkinliği, sınırsız sayıda argümanın komut dosyasından geçmesine izin vererek BÜYÜK BİR şekilde iyileştirilebilir. $ @ Değişkenini geçerseniz, bu aslında nispeten kolaydır. Bunun işlevselliğini genişletmek, örneğin find's -exec + işlevini kullanmamıza veya xargs kullanmamıza izin verir. Bunu çabucak uygulayabilir ve kendi cevabımı geliştirebilirim, ancak bu bir başlangıç.

Bu tek seferlik bir komut dosyası oturumu olduğu için muhtemelen yapılabilecek birçok gelişme var. İyi şanslar!

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.