Bagaimana cara membuat daftar file yang diubah dalam rentang waktu tertentu?

38

Bagaimana saya bisa mendaftar secara rekursif semua file yang diubah antara 22.12.2011 dan 24.12.2011?

penjepit
sumber
6
Jika yang Anda maksud adalah 'perubahan terakhir', Anda memiliki peluang pada solusi. Jika suatu file diubah pada 26.12.2011, Anda tidak dapat mengetahui apakah itu juga dimodifikasi selama rentang yang Anda berikan. (Kecuali jika Anda memiliki sistem file yang sangat eksotis.)
William Pursell

Jawaban:

25

Secara umum, ketika Anda mencari file dalam direktori dan subdirektori secara rekursif, gunakan find.

Cara termudah untuk menentukan rentang tanggal findadalah dengan membuat file pada batas rentang dan menggunakan -newerpredikat.

touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
Gilles 'SANGAT berhenti menjadi jahat'
sumber
mengapa meniadakan output yang pertama -newerdiperlukan di sini?
Alexander Cska
@AlexanderCska Yang pertama -newertidak dinegasikan, yang kedua adalah. "Temukan file yang lebih baru dari starttetapi tidak lebih baru dari stop".
Gilles 'SO- stop being evil'
Ok negasi bekerja pada perintah sesudahnya. Apa yang akan terjadi jika tidak ada negasi yang hadir?
Alexander Cska
@AlexanderCska Maka Anda akan mendapatkan file yang lebih baru dari keduanya startdan stop.
Gilles 'SANGAT berhenti menjadi jahat'
35

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.

Benar
sumber
Trik keren, terima kasih! Itu membantu saya menemukan file terbaru yang mengandung kata kunci tertentu dalam direktori dengan ribuan file: find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l( -m 50= cari di 50 baris pertama).
Rob W
@RobW: Sebenarnya Anda bisa meluangkan pipa dan xargs menggunakan -exec ... +di find(1), seperti: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +. Ini melakukan hal yang sama, tetapi lebih murah.
Benar
Saya harus melampirkan cap waktu dengan tanda kutip ganda (saya menggunakan Ubuntu Xenial with find 4.7.0-git).
IsaacS
13

Selain jawaban yang sudah diberikan, perhatikan bahwa Anda dapat langsung menentukan tanggal Anda:

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

atau

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

jika Anda juga ingin menentukan waktu.

mahasiswa
sumber
6

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 cminmenjadi mminsetelah komentar @ Eelvex. EDIT: '\!' hilang

onur güngör
sumber
hm sepertinya tidak berfungsi. Anda yakin itu berjalan secara rekursif melalui subdirektori?
jepit
Ya, itu berhasil pada saya. Apakah Anda benar-benar memiliki file yang dimodifikasi dalam rentang waktu itu? Cobalah dengan rentang waktu yang berbeda.
onur güngör
6
-cminadalah "perubahan status", -mminadalah "perubahan data". Anda mungkin ingin-mmin
Eelvex
3

finddapat 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
Alex Young
sumber
0

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!

Vex Mage
sumber