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і destдля To_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команди набагато простішими та встановлює змінну на абсолютний шлях dest:
$ cd src
$ destdir="$(readlink -f dest)"
Потім ми перераховуємо всі файли в src:
$ find . -maxdepth 1 -type f
і для кожного знайденого файлу використовуйте, cmpщоб перевірити, чи є в dest файлі однаковий вміст:
$ 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чи іншого, що завадило б перезаписати файли, запитавши спочатку.