22.12.2011 ve 24.12.2011 tarihleri arasında değiştirilen tüm dosyaları tekrarlı olarak nasıl listeleyebilirim?
22.12.2011 ve 24.12.2011 tarihleri arasında değiştirilen tüm dosyaları tekrarlı olarak nasıl listeleyebilirim?
Yanıtlar:
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 -newer
yüklemeyi kullanmaktır .
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
burada gerekli?
-newer
olumsuz değil, ikincisi. “Yeni olan start
ancak yeni olmayan dosyaları bulun stop
”.
start
ve stop
.
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.
find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l
( -m 50
= ilk 50 satırda arama yap).
-exec ... +
içinde find(1)
gibi: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +
. Bu aynı, ancak daha ucuz.
find 4.7.0-git
).
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 cmin
için mmin
Eelvex yorumuna @ sonra.
EDIT: '\!' eksik
-cmin
"durum değişikliği", -mmin
"veri değişikliği" dir. Muhtemelen istiyorsun-mmin
find
tarih 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
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!