การย้ายไฟล์และแจ้งผู้ใช้เมื่อมีชื่อซ้ำกัน:
ในฐานะที่เป็น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
;
\;
\
;
find
find
-exec
;
หากคุณต้องการแสดงรายการไฟล์ - ซึ่งแนะนำให้เลือกหากคุณไม่แน่ใจว่าอีเมลเก่าถูกเก็บไว้อย่างไรหรือมีไฟล์อื่นใดอยู่บ้างละเว้น-exec
และทุกอย่างไปทางขวา (สำหรับอีเมลมักจะเก็บอีเมลจากวันที่แตกต่างกันในไฟล์เดียวกันสำหรับใครบางคนในสถานการณ์ที่อธิบายไว้ในคำถามที่นี่ฉันแนะนำให้ตรวจสอบวิธีการจัดเก็บก่อนที่จะย้ายไฟล์ใด ๆ ) หากคุณต้องการพิมพ์ชื่อและย้าย พวกเขาเพิ่มก่อน-print
-exec
mv -i
แจ้งให้ทุกครั้งที่ไฟล์จะถูกเขียนทับที่ปลายทางเช่นจะเกิดขึ้นหาก:
- ไฟล์ชื่อเดียวกันมีอยู่จากข้อมูลสำรองก่อนหน้าหรือ
- ไฟล์ที่ชื่อเดียวกัน แต่มาจากไดเรกทอรีย่อยที่แตกต่างกันของ
srcdir
ถูกย้ายไปแล้วระหว่างการfind
ดำเนินการเดียวกันหรือ
- (อย่างน้อยน่าจะเป็น)ไฟล์ที่มีชื่อเดียวกันนี้จะถูกสร้างขึ้นที่ไหนสักแห่งใน
srcdir
ระหว่างการfind
ดำเนินการเดียวกันหลังจากที่ย้ายต้นฉบับ แต่ไม่นานพอที่จะพบได้เมื่อfind
สำรวจไดเรกทอรีย่อยอื่น
วิธีอื่นในการเรียกใช้rm
:
คุณมีตัวเลือกอื่น ๆ สำหรับวิธีจัดการไฟล์ที่มีชื่อซ้ำกัน
- หากไม่มี
-i
(เช่น) จะไม่แจ้งให้ขออนุมัติ แต่จะทำเช่นนั้นหากไฟล์ปลายทางเป็นแบบอ่านอย่างเดียว ( อาจประสบความสำเร็จในการเขียนทับไฟล์แบบอ่านอย่างเดียวในบางครั้งเช่นหากผู้ใช้ที่ใช้งานอยู่เป็นเจ้าของไฟล์)mv {} destdir/
mv
mv
- หากคุณไม่ต้องการแม้กระทั่งว่าระดับของการติดต่อสื่อสารและต้องการ
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 q
p -a q
find
-type f
เช่นเดียวกับการทดสอบการดำเนินการประเมินจะจริงหรือเท็จเช่นกัน ด้วยวิธีนี้-exec
รายงานว่าคำสั่งที่ดำเนินการออกจากการรายงานความสำเร็จ (จริง) หรือความล้มเหลว (เท็จ) เรามีห่วงโซ่ของการนี้-exec
การแสดงออกทางเชื่อมต่อกับนัยและ :
-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;
นี้พยายามที่จะย้ายไฟล์และถ้าmv
รายงานความล้มเหลวหยุด เราไม่ต้องการเตือนเกี่ยวกับไฟล์ที่ข้ามอย่างถูกต้องหากมีปัญหาอื่นเกิดขึ้นเพราะเหตุใดไฟล์จึงไม่ถูกย้าย
แต่ถ้ามันประสบความสำเร็จมันก็วิ่งคำสั่ง ชอบ, สนับสนุนชนิดของตัวเองของการแสดงออกผ่านอาร์กิวเมนต์ ตรวจสอบว่าตัวถูกดำเนินการหลังจาก(ส่งผ่านโดยแทนที่) มีอยู่ (และเป็นไฟล์ปกติ) และส่งคืนจริง / สำเร็จหรือเท็จ / ล้มเหลว (สถานะการออกของคำสั่งจำนวนมากตีความได้ดีที่สุดว่าหมายถึงความสำเร็จหรือความล้มเหลว แต่สถานะที่มีอยู่มักตีความได้ดีที่สุดว่าเป็นจริงหรือเท็จ)[
find
[
[ -f {} ]
-f
find
{}
[
หาก[
ส่งคืนเท็จไฟล์จะหายไปดังนั้นจึงถูกย้ายจึงไม่จำเป็นต้องทำอะไรเลย แต่ถ้า[
กลับเท็จไฟล์ยังคงมี จากนั้นfind
ประเมิน-exec
นิพจน์ถัดไปซึ่งพิมพ์ข้อความเตือน
อ่านเพิ่มเติม