Shell Script - รับไฟล์ทั้งหมดที่แก้ไขหลังจาก <date>


136

ฉันไม่อยากทำใน PHP ดังนั้นฉันหวังว่าคนที่เก่งในเชลล์สคริปต์สามารถช่วยได้

ฉันต้องการสคริปต์ที่ทำงานผ่านไดเร็กทอรีซ้ำและพบว่าไฟล์ทั้งหมดที่มีวันที่แก้ไขล่าสุดมากกว่าวันที่บางวัน จากนั้นมันจะ tar และ zip ไฟล์ที่เก็บข้อมูลพา ธ


14
ตัดสินใจได้ดีที่จะไม่ทำใน PHP
Kredns

1
คุณสามารถใช้ภาษาสคริปต์เชลล์ที่เหมาะสมเช่น python, ruby, perl โดยไม่ต้องใช้ php
garrow

3
@garrow สิ่งนี้จะค่อนข้างง่ายใน PHP โดยใช้ RecursiveDirctoryIterator ที่ห่อหุ้มใน FilterIterator
Artefacto

คำตอบ:


137

ง่ายเหมือน:

find . -mtime -1 | xargs tar --no-recursion -czf myfile.tgz

ที่find . -mtime -1จะเลือกไฟล์ทั้งหมดในไดเร็กทอรีปัจจุบัน (เรียกซ้ำ) ที่แก้ไขเมื่อวันก่อน คุณสามารถใช้เศษส่วนได้เช่น:

find . -mtime -1.5 | xargs tar --no-recursion -czf myfile.tgz

4
ดูคำตอบของ user104848 ด้านล่างสำหรับวิธีจัดการกับช่องว่างในชื่อไฟล์ของคุณ
Brian Henk

8
การแปลงการประทับเวลาโดยพลการเป็นเศษส่วนระยะเวลาสัมพัทธ์ดูเหมือนจะไม่ถูกต้องและไม่สะดวกเป็นพิเศษ แก้ปัญหาด้านล่างใช้-newermtเป็นมากดีกว่า
Bobby Jack

5
เมื่อพยายามแตกไฟล์ใด ๆ ที่มีการเปลี่ยนแปลงในโครงสร้างที่มีไดเร็กทอรีไดเร็กทอรีเองจะถูกทำเครื่องหมายว่าแก้ไขทำให้โฟลเดอร์ทั้งหมดถูกเก็บถาวร เพิ่ม-type fเฉพาะไฟล์ที่เลือก สิ่งนี้จะรักษาโครงสร้างโฟลเดอร์ แต่สำรองเฉพาะไฟล์ที่มีการเปลี่ยนแปลง
Brent

1
@BrianHenk user104848 เปลี่ยนชื่อฉันค่อนข้างแน่ใจว่าคุณหมายถึงคำตอบนี้จาก (ปัจจุบัน) Jason Lutherแม้ว่า
icc97

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

94

หากคุณมี GNU แสดงfindว่ามีตัวเลือกที่เกี่ยวข้องมากมาย อุปสรรคเพียงอย่างเดียวคืออินเทอร์เฟซสำหรับพวกเขาน้อยกว่าตัวเอก:

  • -mmin n (เวลาแก้ไขเป็นนาที)
  • -mtime n (เวลาแก้ไขเป็นวัน)
  • -newer file (เวลาแก้ไขใหม่กว่าเวลาแก้ไขไฟล์)
  • -daystart (ปรับเวลาเริ่มต้นจากเวลาปัจจุบันถึงเริ่มต้นวัน)
  • รวมถึงทางเลือกสำหรับเวลาเข้าถึงและเวลา 'เปลี่ยนแปลง' หรือ 'สร้าง'

ส่วนที่ยากคือการกำหนดจำนวนนาทีนับจากเวลา

ทางเลือกหนึ่งที่ควรพิจารณา: ใช้touchเพื่อสร้างไฟล์ที่มีการประทับเวลาแก้ไขที่จำเป็น แล้วใช้findกับ-newer.

touch -t 200901031231.43 /tmp/wotsit
find . -newer /tmp/wotsit -print
rm -f /tmp/wotsit

ค้นหาไฟล์ที่ใหม่กว่า 2009-01-03T12: 31: 43 เห็นได้ชัดว่าในสคริปต์/tmp/wotsitจะเป็นชื่อที่มี PID หรือค่าอื่น ๆ เพื่อให้ไม่ซ้ำกัน และจะต้องมีtrapการตรวจสอบเพื่อให้แน่ใจว่าจะถูกลบออกแม้ว่าผู้ใช้จะขัดจังหวะและอื่น ๆ


68
คุณสามารถใช้-newermt '2009-01-03T12:31:43'เพื่อหลีกเลี่ยงความจำเป็นในการสร้างไฟล์เพื่อการอ้างอิงเท่านั้น
Michael Mior

@ MichaelMior: สิ่งที่น่าสนใจ - 'find' บน MacOS X 10.7.2 รองรับ-newermt(บันทึกไว้ด้านล่าง-newerXYเนื่องจากมีหลายตัวเลือก X = m, Y = t ในกรณีนี้) GNU พบในระบบ Linux (เกือบจะเก่าแก่) ที่ฉันใช้ไม่รองรับตัวเลือกดังนั้นจึงเป็นการมาถึงที่ค่อนข้างเร็ว ขอบคุณสำหรับหัวขึ้น.
Jonathan Leffler

ตัวเลือกนี้มีอยู่ใน GNU ค้นหา 4.4.2 ที่ฉันใช้ในระบบของฉัน
Michael Mior

2
โปรดทราบว่า GNU find รองรับเวลาสัมพัทธ์เช่นกันเช่น -newermt '-2 weeks'.
Cybolic

1
-newermt '2009-01-03T12:31:43'ดูดี แต่น่าเศร้าที่ดูเหมือนว่าจะตีความทุกอย่างในเขตเวลาที่ไม่ถูกต้อง: lists.gnu.org/archive/html/bug-findutils/2012-12/msg00009.html
antoine

35

คุณสามารถทำได้โดยตรงกับน้ำมันดินและดียิ่งขึ้น:

tar -N '2014-02-01 18:00:00' -jcvf archive.tar.bz2 files

คำสั่งนี้สั่งให้ tar บีบอัดไฟล์ที่ใหม่กว่าวันที่ 1 มกราคม 2014 เวลา 18:00:00 น.


9
หึ ... ฉันใช้ Unix มาตั้งแต่ปี 1984 และไม่เคยรู้เรื่องนี้มาก่อน มีอะไรให้เรียนรู้เสมอ
John

การใช้งานของtarที่มาพร้อมกับ OS X และ FreeBSD สนับสนุนเฉพาะ--newerซึ่งเป็นตัวเลือกนานสำหรับ-Nใน tarGNU
nisetama

มันยอดเยี่ยมมาก ... ฉันสามารถทำให้มันทำงานกับ bzip เท่านั้นไม่ได้ใช้ -xcvf และส่วนขยาย gz ... แต่ฉันไม่ใช่ผู้เชี่ยวชาญ
phil

17

วิธีนี้จะใช้ได้กับไฟล์บางไฟล์ คุณต้องการรวม "-print0" และ "xargs -0" ในกรณีที่เส้นทางใด ๆ มีช่องว่างอยู่ ตัวอย่างนี้ค้นหาไฟล์ที่แก้ไขในช่วง 7 วันที่ผ่านมา หากต้องการค้นหาการแก้ไขก่อน 7 วันที่ผ่านมาให้ใช้ "+7"

find . -mtime -7 -print0 | xargs -0 tar -cjf /foo/archive.tar.bz2

ตามที่หน้านี้เตือน xargs อาจทำให้คำสั่ง tar ถูกเรียกใช้หลายครั้งหากมีอาร์กิวเมนต์จำนวนมากและแฟล็ก "-c" อาจทำให้เกิดปัญหาได้ ในกรณีนั้นคุณต้องการสิ่งนี้:

find . -mtime -7 -print0 | xargs -0 tar -rf /foo/archive.tar

คุณไม่สามารถอัปเดตไฟล์ tar แบบซิปด้วย tar ได้ดังนั้นคุณจะต้อง bzip2 หรือ gzip ในขั้นตอนที่สอง


1
ในประเด็นที่สองคุณสามารถใช้คำสั่ง tar ที่เปิดใช้งาน gzip เช่นตัวเลือก -z ของ Gnu tar เพื่ออัปเดตไฟล์เก็บถาวรที่บีบอัดได้เช่นกัน
Suncat2000

หรือเพิ่มตัวเลือก 'j' เพื่อใช้ bzip ใน GNU tars ล่าสุด
hd1

3
ดังที่ฉันได้กล่าวไว้ข้างต้นเกี่ยวกับคำตอบของโจนาธานสิ่งนี้จะดึงโฟลเดอร์ที่มีการเปลี่ยนแปลงทำให้ไฟล์ทั้งหมดถูกนำเข้า เพิ่ม-type fเฉพาะไฟล์ที่เลือก สิ่งนี้จะรักษาโครงสร้างโฟลเดอร์ แต่จะสำรองเฉพาะไฟล์ที่มีการเปลี่ยนแปลง / เพิ่มล่าสุดเท่านั้น
Brent

12

ควรแสดงไฟล์ทั้งหมดที่แก้ไขภายใน 7 วันที่ผ่านมา

find . -type f -mtime -7 -print

บีบลงในน้ำมันดิน / ซิปและคุณควรจะดี


4

ฉันจะทำสิ่งต่อไปนี้เพื่อสำรองไฟล์ใหม่ทั้งหมดจาก 7 วันที่แล้ว

tar --newer $(date -d'7 days ago' +"%d-%b") -zcf thisweek.tgz .

โปรดทราบว่าคุณสามารถแทนที่ '7 วันที่แล้ว' ด้วยอะไรก็ได้ที่เหมาะกับความต้องการของคุณ

เป็นไปได้ : date -d'yesterday' +"%d-%b"

หรือแม้กระทั่ง : date -d'first Sunday last month' +"%d-%b"


3

ภายใต้ linux ลองอ่าน man page ของคำสั่ง find

man find

สิ่งนี้ควร

 find . -type f -mtime -7 -print -exec cat {} \; | tar cf - | gzip -9

และคุณมีมัน


3

คุณสามารถรับรายชื่อไฟล์ที่แก้ไขล่าสุดหลังจาก x วันที่แล้วด้วย:

find . -mtime -x

จากนั้นคุณต้อง tar และ zip ไฟล์ในรายการผลลัพธ์เช่น:

tar czvf mytarfile.tgz `find . -mtime -30`

สำหรับไฟล์ทั้งหมดที่แก้ไขในช่วงเดือนที่แล้ว


3
"-mtime x" ตรงกับไฟล์ที่แก้ไข "x" วันที่แล้วทุกประการใช้ "-mtime -x" เพื่อจับคู่ไฟล์ที่แก้ไขน้อยกว่า "x" วันที่ผ่านมา
Lance Richardson

2

สคริปต์นี้จะค้นหาไฟล์ที่มีวันที่แก้ไขสองนาทีก่อนและหลังวันที่ที่กำหนด (และคุณสามารถเปลี่ยนค่าในเงื่อนไขตามความต้องการของคุณ)

PATH_SRC="/home/celvas/Documents/Imp_Task/"
PATH_DST="/home/celvas/Downloads/zeeshan/"

cd $PATH_SRC
TODAY=$(date  -d "$(date +%F)" +%s)
TODAY_TIME=$(date -d "$(date +%T)" +%s)


for f in `ls`;
do
#       echo "File -> $f"
        MOD_DATE=$(stat -c %y "$f")
        MOD_DATE=${MOD_DATE% *}
#       echo MOD_DATE: $MOD_DATE
        MOD_DATE1=$(date -d "$MOD_DATE" +%s)
#       echo MOD_DATE: $MOD_DATE

DIFF_IN_DATE=$[ $MOD_DATE1 - $TODAY ]
DIFF_IN_DATE1=$[ $MOD_DATE1 - $TODAY_TIME ]
#echo DIFF: $DIFF_IN_DATE
#echo DIFF1: $DIFF_IN_DATE1
if [[ ($DIFF_IN_DATE -ge -120) && ($DIFF_IN_DATE1 -le 120) && (DIFF_IN_DATE1 -ge -120) ]]
then
echo File lies in Next Hour = $f
echo MOD_DATE: $MOD_DATE

#mv $PATH_SRC/$f  $PATH_DST/$f
fi
done

ตัวอย่างเช่นคุณต้องการให้ไฟล์มีวันที่แก้ไขก่อนวันที่ที่กำหนดเท่านั้นคุณอาจเปลี่ยน120เป็น0ใน$DIFF_IN_DATEพารามิเตอร์โดยทิ้งเงื่อนไขของ$DIFF_IN_DATE1พารามิเตอร์

ในทำนองเดียวกันถ้าคุณต้องการไฟล์ที่มีวันที่แก้ไข 1 ชั่วโมงก่อนและหลังวันที่กำหนดเพียงแทนที่120โดยใน3600if CONDITION

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