ฉันจะแสดงรายการไฟล์ทั้งหมดซ้ำที่เปลี่ยนระหว่าง 22.12.2011 ถึง 24.12.2011 ได้อย่างไร
ฉันจะแสดงรายการไฟล์ทั้งหมดซ้ำที่เปลี่ยนระหว่าง 22.12.2011 ถึง 24.12.2011 ได้อย่างไร
คำตอบ:
find
โดยทั่วไปเมื่อคุณกำลังมองหาไฟล์ในไดเรกทอรีและไดเรกทอรีย่อยซ้ำใช้
วิธีที่ง่ายที่สุดในการระบุช่วงวันที่ด้วยfind
คือการสร้างไฟล์ที่ขอบเขตของช่วงและใช้เพ-newer
รดิเคต
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
จึงจำเป็นที่นี่?
-newer
ไม่ได้ถูกปฏิเสธคนที่สองคือ “ ค้นหาไฟล์ที่ใหม่กว่าstart
แต่ไม่ใหม่กว่าstop
”
start
stop
การใช้วิธีการแก้ปัญหาของ 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 บรรทัดแรก)
-exec ... +
ในเช่น:find(1)
find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +
สิ่งนี้ทำเช่นเดียวกัน แต่ถูกกว่า
find 4.7.0-git
)
นอกจากคำตอบที่ได้รับแล้วโปรดทราบว่าคุณสามารถระบุวันที่ได้โดยตรง:
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"
หากคุณต้องการระบุเวลาเพิ่มเติม
สมมติว่าคุณไม่ต้องการความแม่นยำเป็นวินาทีสิ่งนี้น่าจะใช้ได้
find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))
แก้ไข:เปลี่ยนcmin
เป็นmmin
หลังจากความคิดเห็นของ @ Eelvex
แก้ไข: '\!' หายไป
-cmin
คือ "การเปลี่ยนแปลงสถานะ" -mmin
คือ "การเปลี่ยนแปลงข้อมูล" คุณอาจต้องการ-mmin
find
สามารถใช้รูปแบบ ISO datetime ในรูปแบบดังนั้นสำหรับเซิร์ฟเวอร์บน UTC คุณสามารถระบุออฟเซ็ตจำนวนชั่วโมงจากที่ใดก็ได้ นอกจากนี้ยังต้องระมัดระวังในการเพิ่มวันเนื่องจากคุณเปรียบเทียบเวลาด้วย:
find -type f -newermt 20111224T0800 \! -newermt 20111225T0800
โปรดทราบว่าคำถามที่ทำเครื่องหมายว่าซ้ำซ้อนดังนั้นจึงถูก จำกัด ไม่ให้ตอบคำถามโดยตรงนั่นคือสาเหตุที่ฉันโพสต์ที่นี่ คำตอบนี้มีไว้สำหรับตอบคำถาม "ต้องการย้ายไฟล์ไปยังโฟลเดอร์อื่นตามวันที่สร้าง [ซ้ำ]"
คำตอบนั้นสมเหตุสมผล แต่มีข้อ จำกัด บางประการด้วยคำสั่ง 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 ได้เช่นกัน ฉันอาจนำไปใช้อย่างรวดเร็วและปรับปรุงคำตอบของฉันเอง แต่นี่เป็นการเริ่มต้น
เนื่องจากนี่เป็นเซสชันสคริปต์หนึ่งนัดอาจมีการปรับปรุงหลายอย่างที่สามารถทำได้ โชคดี!