Я скопировал некоторые файлы из исходной папки в папку назначения, используя следующую командную строку в терминале.
sudo cp From_SOURCE/* To_DESTINATION/
Теперь я хочу отменить эту команду.
решение1
Если я правильно понял, то дело обстоит следующим образом:
- Вы скопировали (предположительно большое) количество файлов в существующий каталог и хотите отменить действие.
- Целевой каталог содержит ряддругойфайлы, которые вам нужно там хранить, что делает невозможным их простое удалениевсефайлы из каталога
Скрипт ниже ищет в исходном (исходном) каталоге и перечисляет эти файлы. Затем он ищет в каталоге, в который вы скопировали файлы, и удаляет только перечисленные файлы, поскольку они существуют в исходном каталоге.
Элемент try
добавлен для предотвращения ошибок, например, в случае, если вы уже удалили некоторые файлы вручную или если не все файлы из исходного каталога были скопированы в место назначения. Если вам нужны привилегии sudo, просто запустите скрипт с помощью "sudo" (см. ниже).
Сценарий
#!/usr/bin/env python
import os
source_dir = "/path/to/source" # the folder you copied the files from
target_folder = "/path/to/destination" # the folder you copied the files to
for root, dirs, files in os.walk(source_dir):
for name in files:
try:
os.remove(target_folder+"/"+name)
except FileNotFoundError:
pass
Как использовать
- Вставьте скрипт в пустой файл, сохраните его как
reverse.py
, - Вставьте правильные пути для исходной и целевой папки,
- Сделайте его исполняемым для удобства,
Запустите его командой:
[sudo] /path/to/reverse.py
Предупреждение
Сначала попробуйте на тестовом каталоге, если я правильно понял, чего вам нужно добиться!
Если исходный каталог «плоский»
Если исходный каталог не имеет подкаталогов, скрипт может быть еще проще:
#!/usr/bin/env python
import os
source_dir = "/path/to/source" # the folder you copied the files from
target_folder = "/path/to/destination" # the folder you copied the files to
for file in os.listdir(source_dir):
try:
os.remove(target_folder+"/"+file)
except FileNotFoundError:
pass
Примечание
Если копировать действиеперезаписано(заменил) файл с похожим именем в месте назначения, файл будет удален, но исходный файл (конечно) не будет возвращен скриптом. Предполагается, что нет никаких конфликтов имен.
решение2
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
или что-то в этом роде, что предотвратило бы перезапись файлов, спросив об этом заранее.
решение3
Это старый вопрос, но я просто хотел опубликовать ответ на чистом bash:
Сначала перейдите в каталог, куда вы скопировали файлы.
cd dest
Затем ls
исходный каталог и вывод перенаправляем вrm
ls source | xargs rm
решение4
Это ответ, основанный на временной метке операции копирования. Вы можете перечислить содержимое папки в порядке времени создания и передать его в файл:
ls -alt | file_list
Затем откройте file_list
и найдите файлы с той же временной меткой операций копирования. Предположительно, это будут самые последние файлы.
Затем отредактируйте file_list
ненужные rm -rf
файлы/папки и сохраните.
Затем сделайте следующее:
source file_list