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
или так, который бы предотвратил перезапись файлов, сначала спросив.