Согласно этому вопросу и ответу: удалите файл, но исключите все файлы в списке
Этот код делает точно, в чем я нуждаюсь, кроме него не работает над подкаталогами.
for i in *; do
if ! grep -qxFe "$i" filelist.txt; then
echo "Deleting: $i"
# the next line is commented out. Test it. Then uncomment to removed the files
# rm "$i"
fi
done
Это, кажется, просто соответствует на тексте в текстовом файле, а не рассматривает каждую новую строку как путь. Так, когда текстовый файл содержит:
./leaveme.jpg
./i am staying.gif
./james/leaveme.gif
./james/
Это все еще пытается удалить james каталог? Это также игнорирует любые другие файлы в james каталоге, который должен быть удален.
Есть ли какой-либо способ заставить это распознавать полные пути в текстовом файле? У меня есть тысячи подкаталогов, настолько запускающих этот скрипт на каждом отдельном каталоге, взял бы навсегда.
Я также попробовал rsync:
rsync --dry-run -v -r --remove-source-files \
--exclude-from='excludefile.txt' ./source ./to_delete
но если мой excludefile.txt похож на это:
./leaveme.jpg
./i am staying.gif
./james/leaveme.gif
пробный прогон говорит, что переместит./получаем каталогов, а также./source/james каталог? Очевидно, если я поместил./james в текстовый файл затем, он ничего не переместит в рамках того каталога, таким образом, это будет одно экстремальное значение к другому!
Предположим, ваш exclude.txt
выглядит следующим образом:
leaveme.jpg
i am staying.gif
james/leaveme.gif
и все подкаталоги и файлы расположены в , один родительский каталог и ваш exclude.txt
вместе с delete.sh
находятся вне этого родительского каталога.
Приведенный ниже сценарий выполняет следующие действия:
exclude.txt
построчно. .KEEP
. .KEEP
, и удалите их. .KEEP
из сохраненных файлов, вернув им их исходные имена. При запуске скрипт выполняет все указанные выше действия немедленно . Не запускайте его в своем фактическом каталоге, пока не протестируете его сначала, чтобы убедиться, что результаты соответствуют вашим ожиданиям.
Чтобы сначала протестировать сценарий, запустите его в поддельном каталоге копии, аналогичном по структуре и названию желаемому каталогу.
Вы также можете увидеть, какие файлы будут удалены первыми, прежде чем удалять их, изменив эту строку:
find "$path" -type f ! -name "*.KEEP" -exec rm {} \;
этой строкой:
find "$path" -type f ! -name "*.KEEP" -exec echo {} "Will be deleted!" \;
на шаге 2 ниже, чтобы просто напечатать имена файлов. должны быть удалены вместо фактического удаления.
Чтобы создать и использовать сценарий, выполните следующие действия:
Создайте и отредактируйте файл сценария в вашем домашнем каталоге и назовите его delete.sh
, запустив следующую команду в терминале:
nano ~ / delete.sh
Скопируйте и вставьте следующий код в редактор, заменив / path / to / parent / directory /
указав полный путь к каталогу, содержащему файлы, которые необходимо удалить, и заменив /path/to/exclude.txt
на полный путь к вашему exclude.txt
:
#!/bin/bash
path="/path/to/parent/directory/"
filelist="/path/to/exclude.txt"
while IFS=$'\n' read filename
do
mv -n "$path$filename" "$path$filename.KEEP"
done < "$filelist"
find "$path" -type f ! -name "*.KEEP" -exec rm {} \;
find "$path" -type d -empty -delete
while IFS=$'\n' read filename
do
mv -n "$path$filename.KEEP" "$path$filename"
done < "$filelist"
Сохранить файл сценария и выйдите из редактора, нажав Ctrl + X , затем нажмите Y .
Сделайте файл сценария исполняемым, запустив следующую команду в терминале:
chmod + x ~ / delete.sh
Запустите сценарий, выполнив следующую команду в терминале:
bash ~ / delete .sh
Готово, в родительском каталоге остаются только файлы, перечисленные в exclude.txt
.
Можно использовать find . -type f
перечислять все файлы рекурсивно с их полным путем. -type f
опускает все каталоги и перечисляет только файлы. Но здесь filelist.txt
должен содержать полные пути в файлы, которые мы должны исключить из удаления.
for i in $(find . -type f); do
if ! grep -qxFe "$i" filelist.txt; then
echo "Deleting: $i"
# the next line is commented out. Test it. Then uncomment to remove the files
# rm "$i"
fi
done
попытайтесь использовать rsync
с помощью исключать опцию как следующее:
rsync --dry-run -v -r --remove-source-files \
--exclude-from='/path/to/excludefile.txt' /path/to/source/ /path/to/somewhere/to_delete
примечания:
--dry-run
режим; удалите его для принятия реальных мер.excludefile.txt
расположен из /path/to/source
путь, или добавляют себя к excludefile.txt
файл для исключения этого также из удаления также.rsync не может удалить пустые каталоги, если был кто-либо после завершенной операции, таким образом, Вы должны будете удалить их вручную, попробовать
find /path/to/source -type d -empty -ok rmdir {} \;
измените команду на ниже, если Вы не хотите, подтверждают для удаления для каждого каталога.
find /path/to/source -type d -empty -delete
/path/to/somewhere/to_delete
каталог, который Вы указали в команде; таким образом, можно легко перепроверить и удалить все.