วิธีค้นหาไฟล์ระหว่างวันที่สองวันโดยใช้“ ค้นหา”


21

ฉันมีบัญชีอีเมลที่ส่งอีเมล 60GB และในปัจจุบันฉันมีปัญหามากมายในการใช้โปรแกรมรับส่งอีเมลเพื่อเก็บถาวรอีเมลของปีที่แล้ว (2011)

ผ่านเทอร์มินัลฉันพยายามใช้findเพื่อค้นหาไฟล์ระหว่าง 2011-01-01 และ 2011-12-31 แต่ก็ไม่มีประโยชน์

ฉันจะค้นหาไฟล์ระหว่างวันที่สองวันได้อย่างไร

หากเกี่ยวข้องเป้าหมายสุดท้ายจะเป็นชุดที่จะย้ายแต่ละไฟล์ที่พบซึ่งตรงกับช่วงวันที่ไปยังโฟลเดอร์


@EliahKagan ในเวลานั้นหากหน่วยความจำให้บริการชื่อซ้ำกันไม่ได้เป็นปัญหา อย่างไรก็ตามหากคุณป้อนข้อมูลให้กับคุณข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อใดก็ตามจะได้รับการชื่นชมเสมอ :) นอกจากนี้ฉันยังได้รับการโหวตคำตอบของคุณเพราะมันให้ข้อมูลเชิงลึกเพิ่มเติมในหัวข้อนี้
Zuul

@EliahKagan ในกรณีที่ผมแนะนำให้คุณให้คำตอบกับการปฏิบัติไม่ปลอดภัยคุณไฮไลต์ :)
Zuul

คำตอบ:


16

คุณสามารถใช้สคริปต์นี้:

#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
  mv $i /moved_emails_dir/
done

6
เอาต์พุตของfindไม่ควรถูกประมวลผลใน shell forloop เช่นนี้ยกเว้นเมื่อมีการรับประกันว่าไม่มีไฟล์ใด ๆ ที่มีช่องว่างในชื่อ -exec, -execdirหรือ-print0 | xargsควรใช้แทน; วิธีแก้ปัญหาที่เป็นไปได้อีกวิธีหนึ่งซึ่งโดยทั่วไปมักไม่ค่อยเป็นที่พึงปรารถนา แต่อนุญาตให้ใช้forวงวนได้เป็นการตั้งค่าชั่วคราวIFSเพื่อให้มีการเว้นวรรคไม่รู้จักเป็นตัวคั่นฟิลด์
Eliah Kagan

@EliahKagan ดังนั้นคำสั่งจะเป็นอย่างไร: แค่แทนที่findด้วยexec? คุณต้องการเพิ่มคำตอบที่กล่าวถึงการใช้พื้นที่หรือไม่? ชื่นชมมาก
SherylHohman

3
@SherylHohman ไม่ไม่ต้องใช้execคำสั่ง ใช้findคำสั่งที่มี-execแอคชั่นเพื่อเรียกใช้mvหรืออะไรก็ตามที่คุณต้องใช้ตามที่อธิบายไว้ในคำตอบที่ฉันโพสต์ไว้ เมื่อfind... -execรันคำสั่งของคุณกับ pathnames ก็พบว่ามันไม่ได้ใช้เปลือกดังนั้นช่องว่างที่ไม่ได้เรียกแยกคำหรือglobbing (คุณอาจต้องการโพสต์คำถามใหม่เกี่ยวกับกรณีเฉพาะของคุณหรือถามสิ่งที่คุณต้องการทราบอย่างแน่นอน)
Eliah Kagan

@EliahKagan ขออภัยฉันอ่านโพสต์ของคุณผิดและมันมาจากคุณ ! คุณเจ๋งมาก! โพสต์ของคุณยอดเยี่ยมมากและขอบคุณสำหรับการตอบสนองแม้ว่ามันจะเป็นข้อผิดพลาดในการอ่านของฉัน !!
SherylHohman

40

ทุบตีค้นหาไฟล์ระหว่างวันที่สองวัน:

find . -type f -newermt 2010-10-07 ! -newermt 2014-10-08

ส่งคืนรายการไฟล์ที่มีการประทับเวลาหลังจาก 2010-10-07 และก่อน 2014-10-08

Bash ค้นหาไฟล์จาก 15 นาทีที่ผ่านมาจนถึงตอนนี้:

find . -type f -mmin -15

ส่งคืนรายการไฟล์ที่มีการประทับเวลาหลังจาก 15 นาทีก่อน แต่ก่อนตอนนี้

ทุบตีค้นหาไฟล์ระหว่างสองการประทับเวลา:

find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"

ส่งคืนไฟล์ที่มีการประทับเวลาระหว่าง2014-10-08 10:17:00และ2014-10-08 10:53:00


10

การย้ายไฟล์และแจ้งผู้ใช้เมื่อมีชื่อซ้ำกัน:

ในฐานะที่เป็นSubv3rsion ของและเอริค Leschinski ของคำตอบที่แสดงการ-newermtวินิจฉัยเลือกไฟล์ที่แก้ไขเมื่อเร็ว ๆ นี้กว่าวันที่ (และเวลาที่ไม่จำเป็น) ระบุเป็นตัวถูกดำเนินการของ เพื่อค้นหาไฟล์

  • ที่ใดก็ได้ในsrcdir(เช่นรวมถึงไดเรกทอรีย่อยไดเรกทอรีย่อย ฯลฯ )
  • แก้ไขล่าสุดใน (ตัวอย่าง) กันยายน 2014
  • และย้ายไปที่destdir

... คุณสามารถเรียกใช้:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;

ในการแสดงออกผ่านการค้นหาชื่อไฟล์ที่พบในสถานที่ของ-exec บ่งบอกว่าคำสั่งที่จะรันและอาร์กิวเมนต์มีการจัดเตรียมไว้ทั้งหมด (ในกรณีที่นิพจน์ที่ตามมาถูกส่งผ่านเพื่อค้นหาหลังจากอาร์กิวเมนต์ของเพรดิเคตนั้น - ดูตัวอย่างด้านล่างนี้) ต้องหลบหนีเพราะมันไม่ได้ถูกตีความเป็นพิเศษโดยเชลล์ (ไม่, จะจบคำสั่งทั้งหมด, ทำงานเหมือนกับ newline. แม้ว่าคำสั่งนี้จะไม่มีอะไรหลังจากนิพจน์นี้, การไม่ผ่านอาร์กิวเมนต์ก็ยังเป็นข้อผิดพลาดทางไวยากรณ์){};-exec-exec;\;\;findfind-exec;

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

mv -i แจ้งให้ทุกครั้งที่ไฟล์จะถูกเขียนทับที่ปลายทางเช่นจะเกิดขึ้นหาก:

  • ไฟล์ชื่อเดียวกันมีอยู่จากข้อมูลสำรองก่อนหน้าหรือ
  • ไฟล์ที่ชื่อเดียวกัน แต่มาจากไดเรกทอรีย่อยที่แตกต่างกันของsrcdirถูกย้ายไปแล้วระหว่างการfindดำเนินการเดียวกันหรือ
  • (อย่างน้อยน่าจะเป็น)ไฟล์ที่มีชื่อเดียวกันนี้จะถูกสร้างขึ้นที่ไหนสักแห่งในsrcdirระหว่างการfindดำเนินการเดียวกันหลังจากที่ย้ายต้นฉบับ แต่ไม่นานพอที่จะพบได้เมื่อfindสำรวจไดเรกทอรีย่อยอื่น

วิธีอื่นในการเรียกใช้rm:

คุณมีตัวเลือกอื่น ๆ สำหรับวิธีจัดการไฟล์ที่มีชื่อซ้ำกัน

  • หากไม่มี-i(เช่น) จะไม่แจ้งให้ขออนุมัติ แต่จะทำเช่นนั้นหากไฟล์ปลายทางเป็นแบบอ่านอย่างเดียว ( อาจประสบความสำเร็จในการเขียนทับไฟล์แบบอ่านอย่างเดียวในบางครั้งเช่นหากผู้ใช้ที่ใช้งานอยู่เป็นเจ้าของไฟล์)mv {} destdir/mvmv
  • หากคุณไม่ต้องการแม้กระทั่งว่าระดับของการติดต่อสื่อสารและต้องการmvเสมอที่จะ (พยายามที่จะ) mv -fไฟล์เขียนทับชื่อเหมือนกันใช้
  • หากตรงกันข้ามคุณต้องการข้ามไฟล์ต้นฉบับเมื่อมีไฟล์ปลายทางที่ใช้ชื่อเดียวกันmv -nอยู่แล้ว
  • mvยอมรับ-bและตั้ง--backupค่าสถานะเพื่อเปลี่ยนชื่อไฟล์ที่มีชื่อเหมือนกันซึ่งมีอยู่ที่ปลายทางโดยอัตโนมัติ โดยดีฟอลต์~จะถูกเพิ่มเพื่อสร้างชื่อการสำรองข้อมูลและหากไฟล์ที่มีชื่อและไฟล์ที่มีชื่อการสำรองข้อมูลมีอยู่ที่ปลายทางไฟล์สำรองจะถูกเขียนทับ ค่าเริ่มต้นนี้สามารถแทนที่ได้โดยตัวเลือกที่ส่งผ่านเมื่อเรียกใช้mvและตามตัวแปรสภาพแวดล้อม ดูman mvรายละเอียดและตัวอย่างด้านล่าง

การย้ายไฟล์และสร้างการสำรองข้อมูลในกรณีที่มีชื่อซ้ำกัน:

หากต้องการย้ายไฟล์ทั้งหมดให้สำรองไฟล์ด้วยชื่อซ้ำโดยใช้~คำต่อท้ายและใช้คำต่อท้ายที่มีหมายเลขเมื่อไฟล์มีอยู่แล้ว (เพื่อหลีกเลี่ยงการเขียนทับสิ่งใด ๆ ) ให้รัน:.~n~.~

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;

หากคุณข้ามไฟล์ที่มีชื่อซ้ำและต้องการทราบว่ามีไฟล์ใด:

หากคุณใช้mv -nและต้องการทราบว่าไฟล์ใดไม่ถูกย้ายเนื่องจากมีไฟล์อื่นที่มีชื่อเหมือนกันวิธีที่ดีที่สุดน่าจะเป็นเพียงแค่เรียกใช้findคำสั่งดั้งเดิมอีกครั้งโดยไม่ต้องทำ-execทุกอย่างทางด้านขวา นี้จะพิมพ์ชื่อของพวกเขา
มันจะพิมพ์ชื่อของไฟล์ที่ตรงกันใด ๆ ที่สร้างขึ้นตั้งแต่ที่คุณรันfind .... -exec ...คำสั่งดั้งเดิมแต่สำหรับแอปพลิเคชันนี้โดยทั่วไปจะไม่มีเลยเมื่อคุณกำลังค้นหาไฟล์ที่มีการปรับเปลี่ยนครั้งเก่า เป็นไปได้ที่จะให้ไฟล์การแก้ไขเวลาที่เก่ากว่าอายุจริงด้วยtouchและกลไกอื่น ๆ แต่ดูเหมือนจะไม่เกิดขึ้นในกรณีนี้โดยที่คุณไม่รู้ตัว

รู้ได้ทันทีเมื่อข้ามไฟล์เนื่องจากชื่อซ้ำ:

mv -nจะไม่รายงานหรือไม่ส่งคืนรหัสการออกพิเศษใด ๆเมื่อไม่อนุญาตให้ย้ายไฟล์ ดังนั้นหากคุณต้องการได้รับแจ้งทันทีเมื่อข้ามไฟล์ในขณะที่findทำงานคุณจะต้องทำขั้นตอนแยกต่างหาก วิธีหนึ่งคือ:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
    -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \; 

ไม่กี่พิจารณาด้านเทคนิคอาจจะเล็ก ๆ น้อย ๆ นี้เตือนไม่ถูกต้องถ้าmvล้มเหลวในการคัดลอกไฟล์สำหรับเหตุผลที่แตกต่างกว่าที่มันมีอยู่ที่ปลายทางและออกรายงานความสำเร็จ ดูเหมือนไม่น่าเป็นไปได้ แต่ฉันไม่แน่ใจว่าเป็นไปไม่ได้ นอกจากนี้ยังอาจทนทุกข์ทรมานกับสภาพการแข่งขัน : มันจะเตือนเมื่อไม่มีข้อผิดพลาดจริงเลยถ้าไฟล์ใหม่ที่มีชื่อเดียวกันถูกสร้างขึ้นในสถานที่เดียวกันในช่วงเวลาสั้น ๆ หลังจากย้ายไฟล์เก่าและก่อนการตรวจสอบ ดูว่ามันถูกลบออก (เมื่อพิจารณาถึงแอปพลิเคชันฉันสงสัยว่าปัญหาจะเกิดขึ้นจริง ๆ ) อาจมีการเขียนใหม่เพื่อตรวจสอบปลายทางก่อนการย้ายไฟล์แทนหลังจาก: เงื่อนไขการแข่งขันจะเกี่ยวข้องกับไฟล์ปลายทางที่สร้างขึ้นใหม่แทนไฟล์ต้นทาง และในขณะที่ข้อผิดพลาดและคำเตือนที่รายงานโดยfindหรือmv(หรือ[แม้ว่าจะมีไม่ควรจะมี) จะถูกเขียนไปข้อผิดพลาดมาตรฐานของเรา...skipped (exists in...เตือนได้รับการเขียนเพื่อการส่งออกมาตรฐาน โดยปกติแล้วทั้งคู่จะปรากฏบนเทอร์มินัลของคุณ แต่สิ่งนี้อาจสำคัญหากคุณกำลังเขียนสคริปต์

ฉันแบ่งคำสั่งนั้นออกเป็นสองบรรทัดเพื่อให้อ่านง่ายขึ้น สามารถเรียกใช้วิธีนั้นได้หรือคุณสามารถลบ\และขึ้นบรรทัดใหม่ (เช่นตัวแบ่งบรรทัด)

findคำสั่งนั้นทำงานอย่างไร

findเพรดิเคตสามารถเป็นการทดสอบ (เช่น-typeและ-newermt) ใช้สำหรับค่าส่งคืนหรือการกระทำ (เช่น-printและ-exec) ซึ่งมักใช้สำหรับผลข้างเคียง

เมื่อไม่มีผู้ประกอบการ (เช่น-aสำหรับและ , -oสำหรับหรือ ) จะจัดระหว่างสำนวน-aบอกเป็นนัย ๆ findพนักงานการประเมินผลการลัดวงจรสำหรับและและหรือ (กล่าวคือ) เป็นจริงเฉพาะถ้านิพจน์pและqเป็นจริงทั้งคู่ดังนั้นไม่จำเป็นต้องประเมินqหากpเป็นเท็จ แม้ว่าเรามักจะไม่คิดในแง่นี้นี่คือเหตุผลที่การทดสอบจะต้องเป็นจริงสำหรับการกระทำหรือการทดสอบในภายหลัง ตัวอย่างเช่นสมมติว่ามาเมื่อไดเรกทอรี มันประเมินเป็นเท็จจึงสามารถข้ามทุกอย่างหลังจากนั้นp qp -a qfind-type f

เช่นเดียวกับการทดสอบการดำเนินการประเมินจะจริงหรือเท็จเช่นกัน ด้วยวิธีนี้-execรายงานว่าคำสั่งที่ดำเนินการออกจากการรายงานความสำเร็จ (จริง) หรือความล้มเหลว (เท็จ) เรามีห่วงโซ่ของการนี้-execการแสดงออกทางเชื่อมต่อกับนัยและ :

-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;

นี้พยายามที่จะย้ายไฟล์และถ้าmvรายงานความล้มเหลวหยุด เราไม่ต้องการเตือนเกี่ยวกับไฟล์ที่ข้ามอย่างถูกต้องหากมีปัญหาอื่นเกิดขึ้นเพราะเหตุใดไฟล์จึงไม่ถูกย้าย

แต่ถ้ามันประสบความสำเร็จมันก็วิ่งคำสั่ง ชอบ, สนับสนุนชนิดของตัวเองของการแสดงออกผ่านอาร์กิวเมนต์ ตรวจสอบว่าตัวถูกดำเนินการหลังจาก(ส่งผ่านโดยแทนที่) มีอยู่ (และเป็นไฟล์ปกติ) และส่งคืนจริง / สำเร็จหรือเท็จ / ล้มเหลว (สถานะการออกของคำสั่งจำนวนมากตีความได้ดีที่สุดว่าหมายถึงความสำเร็จหรือความล้มเหลว แต่สถานะที่มีอยู่มักตีความได้ดีที่สุดว่าเป็นจริงหรือเท็จ)[find[[ -f {} ]-ffind{}
[

หาก[ส่งคืนเท็จไฟล์จะหายไปดังนั้นจึงถูกย้ายจึงไม่จำเป็นต้องทำอะไรเลย แต่ถ้า[กลับเท็จไฟล์ยังคงมี จากนั้นfindประเมิน-execนิพจน์ถัดไปซึ่งพิมพ์ข้อความเตือน

อ่านเพิ่มเติม


เมื่อฉันได้รับเวลาที่ฉันหวังว่าจะเพิ่มส่วนที่เกี่ยวกับการพิจารณาประสิทธิภาพการทำงานและ-exec ... +มีmv -tบางครั้งเร็ว ๆ นี้
Eliah Kagan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.