TL; DR:
ไฟล์ทั้งหมดที่มีอยู่ในทั้งสองsrcและdestสามารถลบออกจากdestเช่นนี้:
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
สำหรับคำอธิบายทีละขั้นตอนดูด้านล่าง
ทำให้ปัญหาง่ายขึ้น:
เพื่อให้เข้าใจสิ่งที่คำสั่งที่เราต้องการเลิกทำจริงเราเริ่มด้วยการทำให้มันง่ายขึ้น:
คำสั่งที่เราต้องการยกเลิกคือ
sudo cp From_SOURCE/* To_DESTINATION/
เพื่อความเข้าใจวิธีการยกเลิกsudoไม่เกี่ยวข้อง
ฉันจะใช้ชื่อไดเรกทอรีsrcสำหรับFrom_SOURCEและสำหรับdestTo_DESTINATION
ตอนนี้คำสั่งของเราคือ:
cp src/* dest/
ถ้าsrcมีแฟ้มf1, f2และf3และไดเรกทอรีd1และd2เปลือกขยายคำสั่งที่ไปที่:
cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
โดยไม่มีตัวเลือกชอบ-r, -Rหรือ-aคำสั่งcpไม่ลอกไดเรกทอรี
นั่นหมายความว่าคำสั่งจะปล่อยพวกเขาออกไปโดยแสดงข้อผิดพลาดสำหรับแต่ละคน:
$ cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
cp: omitting directory 'src/d1'
cp: omitting directory 'src/d2'
destซึ่งหมายความว่าเราได้คัดลอกเฉพาะไฟล์ง่ายและไม่ไดเรกทอรีไป
การตัดสินใจว่าจะลบไฟล์ใด:
อาจมีไฟล์ในชื่อเดียวกับไฟล์ในdest srcในกรณีนี้ไฟล์ถูกเขียนทับ (1) สายเกินไปสำหรับพวกเขาขอโทษ รับพวกเขากลับจากการสำรองข้อมูลล่าสุด
เกี่ยวกับไฟล์ที่มีเราต้องการลบเฉพาะไฟล์ที่ถูกคัดลอก ไฟล์เหล่านี้มีอยู่ในทั้งสองไดเรกทอรีโดยใช้ชื่อเดียวกันและมีเนื้อหาเหมือนกัน
ดังนั้นเราจึงมองหาไฟล์เหล่านี้:
อันดับแรกเราcdเข้าไปsrcเพราะจะทำให้findคำสั่งต่อไปนี้ง่ายขึ้นมากและตั้งค่าตัวแปรเป็นเส้นทางสัมบูรณ์ของปลายทาง:
$ cd src
$ destdir="$(readlink -f dest)"
จากนั้นเราจะแสดงรายการไฟล์ทั้งหมดใน src:
$ find . -maxdepth 1 -type f
และสำหรับแต่ละไฟล์ที่พบให้ใช้cmpเพื่อตรวจสอบว่ามีไฟล์ที่มีเนื้อหาเดียวกันในปลายทางหรือไม่:
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -print
การลบไฟล์อย่างระมัดระวัง:
ไฟล์เหล่านี้เป็นไฟล์ที่เราต้องการลบ แต่เพื่อให้แน่ใจว่าเราย้ายพวกเขาไปยังไดเรกทอรีที่แตกต่างกันก่อน - และดูคำสั่งก่อนที่จะใช้พวกเขา:
$ toDelete=/tmp/toDelete ; mkdir -p "$toDelete"
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec echo mv -n "$destdir/{}" "$toDelete"/ \;
mv -n /path/to/dest/./f1 /tmp/toDelete/`
mv -n /path/to/dest/./f2 /tmp/toDelete/`
mv -n /path/to/dest/./f3 /tmp/toDelete/`
ดูดี! ตอนนี้เราสามารถออกจากการechoรันmvคำสั่งจริง:
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
ไฟล์ทั้งหมดจากdestที่ถูกคัดลอกมาsrcและยังคงเหมือนเดิมในsrcและdestในตอนนี้/tmp/toDelete/และสามารถลบออกได้หลังจากดูครั้งสุดท้าย
หมายเหตุ:
(1) ตรวจสอบว่าcpเป็นนามแฝงcp -iหรือไม่นั้นจะป้องกันการเขียนทับไฟล์โดยถามก่อน