จะแสดงรายการไฟล์ที่เปลี่ยนแปลงในช่วงเวลาหนึ่งได้อย่างไร?


38

ฉันจะแสดงรายการไฟล์ทั้งหมดซ้ำที่เปลี่ยนระหว่าง 22.12.2011 ถึง 24.12.2011 ได้อย่างไร


6
หากคุณหมายถึง 'การเปลี่ยนแปลงครั้งสุดท้าย' คุณจะมีโอกาสแก้ปัญหา หากไฟล์นั้นได้รับการแก้ไขเมื่อวันที่ 26.12.2011 คุณจะไม่สามารถบอกได้ว่าไฟล์นั้นถูกแก้ไขหรือไม่ในช่วงที่คุณกำหนด (เว้นแต่คุณจะมีระบบไฟล์ที่แปลกใหม่มาก)
William Pursell

คำตอบ:


25

findโดยทั่วไปเมื่อคุณกำลังมองหาไฟล์ในไดเรกทอรีและไดเรกทอรีย่อยซ้ำใช้

วิธีที่ง่ายที่สุดในการระบุช่วงวันที่ด้วยfindคือการสร้างไฟล์ที่ขอบเขตของช่วงและใช้เพ-newerรดิเคต

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

ทำไมลบล้างผลลัพธ์ของสิ่งแรก-newerจึงจำเป็นที่นี่?
Alexander Cska

@AlexanderCska คนแรก-newerไม่ได้ถูกปฏิเสธคนที่สองคือ “ ค้นหาไฟล์ที่ใหม่กว่าstartแต่ไม่ใหม่กว่าstop
Gilles 'ดังนั้นหยุดความชั่วร้าย'

Ok negation ทำงานกับคำสั่งหลังจากนั้น จะเกิดอะไรขึ้นหากไม่มีการปฏิเสธ
Alexander Cska

@AlexanderCska แล้วคุณจะได้รับแฟ้มที่ใหม่กว่าทั้งสองและstart stop
Gilles 'หยุดความชั่วร้าย'

35

การใช้วิธีการแก้ปัญหาของ Gilles และหลังจากอ่านชายคนนั้นพบ (1)อีกครั้งฉันพบวิธีแก้ปัญหาที่ง่ายขึ้น ตัวเลือกที่ดีที่สุดคือ -newerXY สามารถใช้แฟล็ก m และ t

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

ดังนั้นทางออกคือ

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

ขอบเขตล่างรวมและขอบเขตบนเป็นเอกสิทธิ์ดังนั้นฉันจึงเพิ่ม 1 วันลงไป! และมันก็วนซ้ำ มันทำงานได้ดีในการค้นหา v4.5.9


เคล็ดลับเด็ด ๆ ! ที่ช่วยให้ฉันค้นหาไฟล์ล่าสุดที่มีคำหลักบางคำในไดเรกทอรีที่มีไฟล์นับพัน: find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l( -m 50= ค้นหาใน 50 บรรทัดแรก)
Rob W

@RobW: ที่จริงคุณสามารถสำรองและท่อ xargs ใช้-exec ... +ในเช่น:find(1) find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +สิ่งนี้ทำเช่นเดียวกัน แต่ถูกกว่า
TrueY

ฉันต้องใส่เวลาด้วยเครื่องหมายคำพูดคู่ (ฉันใช้ Ubuntu Xenial ด้วยfind 4.7.0-git)
IsaacS

13

นอกจากคำตอบที่ได้รับแล้วโปรดทราบว่าคุณสามารถระบุวันที่ได้โดยตรง:

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

หรือ

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

หากคุณต้องการระบุเวลาเพิ่มเติม


6

สมมติว่าคุณไม่ต้องการความแม่นยำเป็นวินาทีสิ่งนี้น่าจะใช้ได้

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

แก้ไข:เปลี่ยนcminเป็นmminหลังจากความคิดเห็นของ @ Eelvex แก้ไข: '\!' หายไป


hm ดูเหมือนจะไม่ทำงาน คุณแน่ใจหรือไม่ว่ามันซ้ำ ๆ เดินผ่านไดเรกทอรีย่อย?
หนีบ

ใช่มันทำงานกับฉัน คุณมีไฟล์ที่แก้ไขจริงในช่วงเวลานั้นหรือไม่? ลองด้วยช่วงเวลาที่แตกต่างกัน
onur güngör

6
-cminคือ "การเปลี่ยนแปลงสถานะ" -mminคือ "การเปลี่ยนแปลงข้อมูล" คุณอาจต้องการ-mmin
Eelvex

3

findสามารถใช้รูปแบบ ISO datetime ในรูปแบบดังนั้นสำหรับเซิร์ฟเวอร์บน UTC คุณสามารถระบุออฟเซ็ตจำนวนชั่วโมงจากที่ใดก็ได้ นอกจากนี้ยังต้องระมัดระวังในการเพิ่มวันเนื่องจากคุณเปรียบเทียบเวลาด้วย:

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

0

โปรดทราบว่าคำถามที่ทำเครื่องหมายว่าซ้ำซ้อนดังนั้นจึงถูก จำกัด ไม่ให้ตอบคำถามโดยตรงนั่นคือสาเหตุที่ฉันโพสต์ที่นี่ คำตอบนี้มีไว้สำหรับตอบคำถาม "ต้องการย้ายไฟล์ไปยังโฟลเดอร์อื่นตามวันที่สร้าง [ซ้ำ]"

คำตอบนั้นสมเหตุสมผล แต่มีข้อ จำกัด บางประการด้วยคำสั่ง find ล้วนๆ ฉันเขียนเชลล์สคริปต์นี้เพื่อไปยังไดเรกทอรีที่มีไฟล์จำนวนมากอยู่ในนั้นระบบไฟล์ปิดปากบนเมทาดาทาที่พยายามแสดง ls นอกจากนี้ระบบ * nix บางแห่งจะมีข้อผิดพลาดในการขัดแย้งกับการเรียกใช้ ls มากเกินไป

คำสั่ง find มีประสิทธิภาพมากและฉันเริ่มต้นด้วยวิธีการที่ระบุไว้ แต่ฉันมีข้อมูลหลายปีตลอดไดเรกทอรีที่ฉันต้องผ่านไฟล์ทั้งหมดซ้ำ ๆ สิ่งนี้สร้างการส่งผ่านที่ไม่มีความจำเป็นผ่านแต่ละไฟล์จำนวนมาก ฉันพยายามทำหนึ่งหน้าจอต่อปีและเรียกใช้การค้นหาหลายรายการ แต่สิ่งนี้ส่งผลให้เกิดข้อผิดพลาดจำนวนมากจากการค้นหาแต่ละครั้งและไฟล์จะหายไปเมื่อพบสิ่งใดสิ่งหนึ่งที่ย้ายมัน

เชลล์สคริปต์ของฉันย้ายไฟล์ไปยังไดเรกทอรีปลายทางด้วยปี 4 หลักและเดือน 2 หลัก สามารถขยายได้อย่างง่ายดายเป็นวันที่ 2 หลักโดยไม่แสดงข้อคิดเห็นสองบรรทัดและแสดงความคิดเห็นออกมา ฉันเชื่อว่ามันมีประสิทธิภาพมากกว่าเพราะมันทำการเคลื่อนที่ในการค้นหาครั้งเดียวดังนั้นคำสั่ง find หลายคำสั่งและการส่งผ่านไดเรกทอรีจะไม่จำเป็น

#!/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

เมื่อบันทึกและทำให้สามารถเรียกใช้งานได้คุณสามารถเรียกใช้สคริปต์นี้พร้อมกับค้นหาดังนี้

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

คุณไม่จำเป็นต้องกังวลเกี่ยวกับการตั้งค่าตัวเลือก newermt สำหรับการค้นหาเนื่องจาก find ทั้งหมดกำลังจัดให้มีการประมวลผลครั้งเดียวต่อไฟล์ที่พบและสคริปต์ทำการตัดสินใจทั้งหมด

โปรดทราบว่าหากคุณไม่ได้เลือกประเภทที่จะย้ายไดเรกทอรีรอบและที่อาจทำให้เกิดปัญหา นอกจากนี้คุณยังสามารถใช้ -type d หากคุณต้องการย้ายเฉพาะไดเรกทอรี หากไม่ตั้งค่าประเภทนี้จะทำให้เกิดพฤติกรรมที่ไม่พึงประสงค์

โปรดจำไว้ว่าสคริปต์นี้เหมาะกับความต้องการของฉัน คุณอาจต้องการใช้โครงสร้างของฉันเป็นแรงบันดาลใจให้เหมาะกับสคริปต์ที่คุณต้องการ ขอขอบคุณ!

ข้อควรพิจารณา: ประสิทธิภาพของคำสั่งสามารถปรับปรุงได้อย่างมากโดยการอนุญาตให้มีการขัดแย้งจำนวนไม่ จำกัด ผ่านสคริปต์ นี่ค่อนข้างง่ายถ้าคุณผ่านตัวแปร $ @ การขยายการทำงานของสิ่งนี้จะทำให้เราสามารถใช้ฟังก์ชัน -exec + หรือ find ของ xargs ได้เช่นกัน ฉันอาจนำไปใช้อย่างรวดเร็วและปรับปรุงคำตอบของฉันเอง แต่นี่เป็นการเริ่มต้น

เนื่องจากนี่เป็นเซสชันสคริปต์หนึ่งนัดอาจมีการปรับปรุงหลายอย่างที่สามารถทำได้ โชคดี!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.