Bagaimana saya bisa mendaftar secara rekursif semua file yang diubah antara 22.12.2011 dan 24.12.2011?
Bagaimana saya bisa mendaftar secara rekursif semua file yang diubah antara 22.12.2011 dan 24.12.2011?
Jawaban:
Secara umum, ketika Anda mencari file dalam direktori dan subdirektori secara rekursif, gunakan find
.
Cara termudah untuk menentukan rentang tanggal find
adalah dengan membuat file pada batas rentang dan menggunakan -newer
predikat.
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
diperlukan di sini?
-newer
tidak dinegasikan, yang kedua adalah. "Temukan file yang lebih baru dari start
tetapi tidak lebih baru dari stop
".
start
dan stop
.
Menggunakan solusi Gilles dan setelah membaca lelaki itu menemukan (1) lagi saya menemukan solusi yang lebih sederhana. Pilihan terbaik adalah -newerXY. Bendera m dan t dapat digunakan.
m The modification time of the file reference
t reference is interpreted directly as a time
Jadi solusinya adalah
find . -type f -newermt 20111222 \! -newermt 20111225
Batas bawah inklusif, dan batas atas eksklusif, jadi saya menambahkan 1 hari untuk itu! Dan itu bersifat rekursif. Ini bekerja dengan baik pada find v4.5.9.
find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l
( -m 50
= cari di 50 baris pertama).
-exec ... +
di find(1)
, seperti: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +
. Ini melakukan hal yang sama, tetapi lebih murah.
find 4.7.0-git
).
Dengan asumsi Anda tidak membutuhkan ketelitian pada detik, ini seharusnya bekerja.
find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))
EDIT: Diubah cmin
menjadi mmin
setelah komentar @ Eelvex.
EDIT: '\!' hilang
-cmin
adalah "perubahan status", -mmin
adalah "perubahan data". Anda mungkin ingin-mmin
find
dapat mengambil datetime yang diformat ISO, jadi untuk server di UTC misalnya, Anda dapat menentukan offset beberapa jam dari mana pun Anda berada. Ini juga harus ditambah satu hari karena Anda juga membandingkan waktu:
find -type f -newermt 20111224T0800 \! -newermt 20111225T0800
Harap perhatikan bahwa pertanyaan yang ditandai sebagai rangkap, dan karena itu dibatasi untuk menjawabnya secara langsung, itulah sebabnya saya memposting ke sini. Jawaban ini untuk menjawab pertanyaan "perlu memindahkan file ke folder berbeda berdasarkan tanggal pembuatan [duplikat]"
Jawabannya masuk akal tetapi ada beberapa batasan dengan perintah find murni. Saya menulis skrip shell ini untuk pergi melalui direktori dengan begitu banyak file di dalamnya sistem file tersedak metadata yang mencoba melakukan ls. Selain itu beberapa sistem * nix akan memunculkan kesalahan argumen terlalu banyak dengan menjalankan ls.
Perintah find sangat kuat dan saya mulai dengan metode yang terdaftar tetapi saya memiliki data bertahun-tahun di seluruh direktori itu sehingga saya harus melewati semua file berulang kali. Ini menghasilkan banyak yang tidak perlu melewati setiap file. Saya mencoba melakukan satu layar per tahun dan menjalankan beberapa penemuan tetapi ini menghasilkan banyak kesalahan dari setiap penemuan dan file-file akan hilang ketika salah satu temuan memindahkannya.
Script shell saya memindahkan file ke direktori tujuan, dengan tahun 4 digit dan bulan 2 digit. Ini dapat dengan mudah diperluas menjadi 2 digit hari dengan membatalkan komentar beberapa baris dan berkomentar rekan-rekan mereka. Saya percaya ini lebih efisien karena melakukan gerakan dalam satu pass find sehingga banyak perintah find dan melewati direktori tidak diperlukan.
#!/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
Setelah disimpan dan dapat dieksekusi, Anda dapat memanggil skrip ini dengan find seperti yang berikut ini.
find /path/to/directory -type f -exec /home/username/move_files.sh {} \;
Anda tidak perlu khawatir tentang pengaturan opsi newermt untuk menemukan karena semua find menyediakan adalah eksekusi tunggal per file ditemukan dan script membuat semua keputusan.
Ingatlah bahwa jika Anda tidak memilih -type f, ia akan memindahkan direktori dan itu akan menyebabkan masalah. Anda juga bisa menggunakan -type d jika Anda ingin memindahkan direktori saja. Tidak mengatur jenisnya hampir pasti akan menghasilkan perilaku yang tidak diinginkan.
Ingat bahwa naskah ini disesuaikan dengan kebutuhan saya . Anda mungkin ingin menggunakan konstruksi saya sebagai inspirasi untuk naskah yang lebih sesuai dengan kebutuhan Anda. Terima kasih!
Pertimbangan: Efisiensi perintah dapat sangat ditingkatkan dengan memungkinkan argumen tanpa batas melewati skrip. Ini sebenarnya relatif mudah jika Anda melewati variabel $ @. Memperluas fungsi ini akan memungkinkan kita untuk menggunakan fungsi -exec + fungsi atau leverage xargs, misalnya. Saya dapat dengan cepat mengimplementasikannya dan meningkatkan jawaban saya sendiri tetapi ini adalah awal.
Karena ini adalah sesi skrip satu langkah, mungkin ada banyak perbaikan yang dapat dilakukan. Semoga berhasil!