การย้ายไฟล์และแจ้งผู้ใช้เมื่อมีชื่อซ้ำกัน:
ในฐานะที่เป็น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นิพจน์ถัดไปซึ่งพิมพ์ข้อความเตือน
อ่านเพิ่มเติม