วิธีย้ายไฟล์ตามปี


15

ฉันต้องการย้ายไฟล์ตามปี ฉันใช้findคำสั่ง

find /media/WD/backup/osool/olddata/ -mtime +470 -exec ls -lrth {} \;|sort -k6

แต่สำหรับคำสั่งนี้เพื่อดำเนินการให้สำเร็จฉันจำเป็นต้องรู้แน่นอนmtimeตอนนี้ 470 เป็นเพียงการคาดเดา หมายถึงถ้าฉันสามารถให้ปี 2012 มันให้ไฟล์ที่เกี่ยวข้องกับ 2012

ดังนั้นฉันต้องการคำแนะนำเกี่ยวกับวิธีการ

ค้นหาไฟล์ตามปีเช่น 2012 และย้ายไปยังไดเรกทอรีอื่น

OS release 5.2

FIND version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX 

มันเหมาะสมที่จะใช้-exec ls ... \;แทน-exec ... +? การค้นหาของคุณแก่เกินไปหรือเปล่า ในกรณีfind ... -print0 | xargs -0 ls...นั้นจะเร็วกว่ามาก
Hauke ​​Laging

ฉันต้องการคำถามเหล่านี้ (และคำตอบ) ที่จัดการกับ coreutils เป็นประจำจะระบุว่าเรากำลังเผชิญกับ GNU หรือ BSD (หรืออื่น ๆ )
เขาวงกต

คำตอบ:


39

คุณต้องการใช้-newermtตัวเลือกสำหรับfind:

find /media/WD/backup/osool/olddata/ -newermt 20120101 -not -newermt 20130101

เพื่อรับไฟล์ทั้งหมดพร้อมเวลาการแก้ไขในปี 2555

หากการค้นหาของคุณไม่สนับสนุน-newermtคุณสามารถทำสิ่งต่อไปนี้เพื่อป้องกันการใช้การคำนวณออฟเซ็ต:

touch -d 20120101 /var/tmp/2012.ref
touch -d 20130101 /var/tmp/2013.ref
find /media/WD/backup/osool/olddata/ -newer /var/tmp/2012.ref -not -newer /var/tmp/2013.ref

1
แฟล็ก -newermt ไม่พร้อมใช้งานในคำสั่งค้นหา
OmiPenguin

นั่นต้องเป็นเวอร์ชั่นเก่าของการค้นหาว่า RHEL ของคุณมาพร้อมกับอะไร? ฉันจะให้ทางเลือกในคำตอบสำหรับเรื่องนั้น
Anthon

ใช่อันนี้คือ 5.2
OmiPenguin

ฉันใช้มันนั่นคือการแก้ไข RHEL ไม่ใช่ของfind(ฉันได้พบรุ่น 4.4.2)
Anthon

1
สวิทช์ newermt ไม่แสดงขึ้นในการค้นหาจนถึงรุ่นหลัง v4.3.3, gnu.org/software/findutils/manual/html_mono/find.html
slm

5
touch --date=2011-12-31T23:59:59 start
touch --date=2012-12-31T23:59:59 stop
find / -newer start \! -newer stop -printf %Tx" "%p\\n

-exec ls ไม่สมเหตุสมผล


1
-exec ls -lเหมาะสมมากขึ้นและมากขึ้นขณะทำการทดสอบ
CVn

@ MichaelKjörling findสามารถพิมพ์ทุกอย่างที่lsทำได้ ตกลงมีข้อยกเว้นหนึ่งข้อ: การหลบหนี / การอ้างถึงตัวอักษรที่ไม่พึงประสงค์ แต่โดยทั่วไปผลลัพธ์ของfindสามารถเรียงลำดับได้โดยตรง การเรียกใช้ ls ที่ไร้ประโยชน์ไม่ทำให้ทุกอย่างเร็วขึ้น
Hauke ​​Laging

ฉันมักจะใช้สิ่งที่คล้ายกันมาก (แม้ว่าโดยส่วนตัวแล้วฉันชอบ-printหรืออาจจะเป็น -ls ) ในขณะที่ทำการทดสอบ ประโยชน์ของการใช้-exec ls {}ก็คือว่ามันมีอยู่แล้วดำเนินการบางสิ่งบางอย่างจากภายนอกที่จะหา ดังนั้นเมื่อถึงเวลาที่คุณเปลี่ยนจากlsที่จะmvมีการเปลี่ยนแปลงที่เกิดขึ้นจริงมีน้อย
CVn

3

ตามหน้า man อาร์กิวเมนต์สำหรับ -mtime คือจำนวนวันที่คุณต้องการ คุณสามารถใช้date +%jเพื่อค้นหาจำนวนวันตั้งแต่วันที่ 1 มกราคมของปีปัจจุบัน


2
เป็นวิธีที่ดี ในการเป็น "nitpicky": -mtime -1: เป็นไฟล์ใด ๆ ใน 24 ชั่วโมงที่ผ่านมา ไม่ใช่แค่ไฟล์จากเมื่อวาน (หรือวันนี้) ดังนั้นจะมี "เหลื่อม" เล็กน้อย: หากคุณตรวจสอบว่าเป็น 120 วันตั้งแต่ปี 2012 และวันนี้เป็นเวลา 15:45 เมื่อคุณเปิดใช้งานสคริปต์คุณจะสิ้นสุดการเลือกไฟล์จนถึง 31 ธันวาคม 15:45 ( และไม่ใช่วันสุดท้ายของวันนั้น) ... คุณอาจใช้: nb_day - 1 และจากนั้น "กำจัดวัชพืช" ไม่กี่วันที่ออกจากปี 2013 (เหล่านี้สามารถพบได้โดย ls -l | grep -v, BUT ผลลัพธ์จะแตกต่างกันไปหากมีอายุ 1 วันเท่านั้น ... จำนวนของข้อผิดพลาดมากมาย ... )
Olivier Dulac

คุณไม่ต้องการใช้ตัวเลือกถ้าคุณกำลังจะไปทำงานกับ-daystart -mtimeมิฉะนั้นคุณจะมีปัญหาเกี่ยวกับไฟล์รอบต้นปีและปลายปีไม่ว่าคุณจะเปิดทางใดจนกว่าคุณจะเรียกใช้สิ่งนี้ในเวลาเที่ยงคืน คุณสามารถทำออฟเซ็ตได้แม่นยำ-mminกว่าด้วย-mtimeถ้าคุณสามารถหาจำนวนนาทีตั้งแต่ปีใหม่ได้อย่างง่ายดาย แต่ปัญหาเดียวกันนี้เกิดขึ้นกับ-mtimeไฟล์เพียงเล็กน้อยเท่านั้น (หนึ่งนาทีประมาณเที่ยงคืนปีใหม่)
Anthon

1
ใช่อ่านหน้าคนที่ฉันเห็นว่ามันทำลายลงไปหลายชั่วโมงเพื่อทำง่ายfind -mtime $("date -+%j")อาจจะไม่ให้ OP สิ่งที่พวกเขาจะทำ ฉันทิ้งมันไว้เพื่อลูกหลานแม้ว่าจะเป็นเพราะจุดบอดเป็นไปได้สำหรับคนที่จะตกหลุมรัก
Bratchley

2

คุณสามารถลองใช้การรวมกันกับคำสั่งstatและ / หรือdateคำสั่งดังต่อไปนี้:

BSD / Mac OS X:

find . -type f -print | while read file; do eval `stat -s "$file"`; year=`date -jf "%s" "+%Y" "$st_mtime"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

ลินุกซ์:

find . -type f -print | while read file; do year=`date -r "$file" "+%Y"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

ในทั้งสองกรณีวิธีการคือการใช้dateคำสั่งเพื่อแยกปีจากเวลาแก้ไขล่าสุดของทุกไฟล์แล้วสร้างเส้นทางด้วยปีนี้ คำสั่งmkdir -pจะสร้างเส้นทางนี้หากยังไม่มีอยู่ แน่นอนคุณสามารถใช้findตัวเลือกอื่นเพื่อปรับแต่งการค้นหาของคุณ


1

หากคุณทำสิ่งนี้จากไดเรกทอรีการทำงานคุณสามารถทำสิ่งนี้แทน:

ls -l |awk '{ if ($8 == "2013") print $9 }'

สิ่งนี้ทำให้สิ่งต่าง ๆ ง่ายขึ้นมากและไม่ทำให้เกิดการทับซ้อนกัน แต่ก็สันนิษฐานว่าไฟล์เหล่านี้มีอายุมากกว่า 6 เดือนและlsจะพิมพ์ปีแทนเวลาที่แน่นอน

สำหรับไฟล์ที่เก่ากว่า 6 เดือนคุณจะต้องแทนที่ด้วย:

ls -l |awk '{ if ($6 == "May") print $9 }' 

หรือสิ่งที่คล้ายกันขึ้นอยู่กับเดือน ถ้าคุณต้องการสร้างรายการของเดือนเพื่อย้ายไฟล์สำหรับ (หรือถ้าคุณต้องการสร้างรายการสำหรับปี) ทำสิ่งนี้:

month="May Jun Jul"; 
for i in `echo $month`; 
do 
    for j in `ls -l |awk '{ if ($6 == "'$i'") print $9}'`
    do
        mkdir -p $i
        mv $j $i
    done
done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.