TL; DR:
Semua file yang ada di keduanya src
dan dest
dapat dihapus dari dest
seperti ini:
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
Untuk langkah demi langkah, penjelasan, lihat di bawah.
Menyederhanakan masalah:
Untuk memahami apa yang sebenarnya ingin kami batalkan, kami mulai dengan menyederhanakannya:
Perintah yang ingin kita batalkan adalah
sudo cp From_SOURCE/* To_DESTINATION/
Untuk memahami cara membatalkan, sudo
tidak relevan.
Saya akan menggunakan nama direktori src
untuk From_SOURCE
dan dest
untukTo_DESTINATION
.
Sekarang, perintah kami adalah:
cp src/* dest/
Jika src
berisi file f1
, f2
dan f3
, dan direktori d1
dan d2
, shell memperluas perintah itu ke:
cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
Tanpa opsi seperti -r
, -R
atau -a
, perintah cp
tidak menyalin direktori.
Itu berarti, perintah akan membiarkan mereka keluar, menunjukkan kesalahan untuk masing-masing dari mereka:
$ cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
cp: omitting directory 'src/d1'
cp: omitting directory 'src/d2'
Itu berarti, kami hanya menyalin file sederhana, dan tidak ada direktori, ke dest
.
Memutuskan file mana yang akan dihapus:
Mungkin ada file dest
dengan nama yang sama dengan file dalam src
. Dalam hal ini, file-file tersebut ditimpa (1). Sudah terlambat bagi mereka, maaf. Dapatkan mereka kembali dari cadangan terbaru.
Mengenai file yang ada di sana, kami hanya ingin menghapus file yang sudah disalin. File-file ini ada di kedua direktori, dengan nama yang sama, dan konten yang sama.
Jadi kami mencari file-file ini:
Pertama, kita cd
masuk src
, karena itu membuat find
perintah berikut lebih sederhana, dan menetapkan variabel ke jalur absolut dest:
$ cd src
$ destdir="$(readlink -f dest)"
Lalu, kami daftar semua file di src:
$ find . -maxdepth 1 -type f
dan, untuk setiap file yang ditemukan, gunakan cmp
untuk memeriksa apakah ada file dengan konten yang sama di dest:
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -print
Menghapus file, dengan hati-hati:
File-file ini adalah yang ingin kita hapus. Namun yang pasti, kami memindahkannya ke direktori yang berbeda terlebih dahulu - dan perhatikan perintah sebelum menjalankannya:
$ 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/`
Kelihatan bagus! Sekarang kita bisa membiarkan echo
untuk menjalankan mv
perintah nyata :
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
Semua file dari dest
yang disalin dari src
, dan masih benar-benar sama src
dan dest
, sekarang /tmp/toDelete/
, dan dapat dihapus setelah melihat terakhir.
Catatan:
(1) Periksa apakah cp
alias cp -i
atau lebih, yang akan mencegah menimpa file dengan bertanya terlebih dahulu.