Все мои разделы NTFS принадлежат root, но я могу получить к ним доступ как пользователь.
В моем /etc/fstab разделы включаются следующим образом: [[dl]]
! d1]
UUID=AB84274F84211B98 /media/WIN7 ntfs defaults 0 0
UUID=CDBAF39E13A2AC2D /media/DATA ntfs defaults 0 0
UUID=EFA980B33BA33DF5 /media/MEDIA ntfs defaults 0 0
, где defaults являются параметрами монтирования по умолчанию, которые уже должны делать то, что вы хотите сделать.
Чтобы найти UUID, запустите sudo blkid.
] См. Также: Как использовать 'chmod' в разделе NTFS (или FAT32)?
Этот скрипт python может сделать это:
#!/usr/bin/env python3
import os
no_remove = set()
with open('./dont-delete.txt') as f:
for line in f:
no_remove.add(line.strip())
for f in os.listdir('.'):
if f not in no_remove:
print('unlink:' + f )
#os.unlink(f)
Важная часть состоит в том, чтобы раскомментировать функцию os.unlink().
ПРИМЕЧАНИЕ: добавьте этот скрипт и dont-delete.txt в свой [ f4], чтобы они оба были в списке и сохраняли их в одном каталоге.
Вот один лайнер:
comm -2 -3 <(ls) <(sort dont_delete) | tail +2 | xargs -p rm
ls печатает все файлы в текущем каталоге (в отсортированном порядке) sort dont_delete печатает все файлы, которые мы не хотим удалять в отсортированных чтобы оператор <() превратил строку в файл-подобный объект. Команды comm сравнивают два предварительно отсортированных файла и выводят строки, по которым они отличаются, используя флаги -2 -3, заставляют comm печатать только строки, содержащиеся в первый файл, но не второй, который будет списком файлов, которые безопасны для удаления вызова tail +2, - это просто удалить заголовок выхода comm, который содержит имя входного файла. Теперь мы получаем список файлов для удаления по стандарту. Мы выводим этот вывод на xargs, который превратит выходной поток в список аргументов для rm. Параметр -p заставляет xargs запрашивать подтверждение перед выполнением. FWIW похоже, что вы можете сделать это изначально в zsh, используя квалификатор glob (+cmd).
Чтобы проиллюстрировать, давайте начнем с некоторых файлов
% ls
bar baz bazfoo keepfiles.txt foo kazoo
и файл белого списка
% cat keepfiles.txt
foo
kazoo
bar
Сначала прочитайте белый список в массив:
% keepfiles=( "${(f)$(< keepfiles.txt)}" )
или, возможно, лучше
% zmodload zsh/mapfile
% keepfiles=( ${(f)mapfile[./keepfiles.txt]} )
(эквивалент bash's mapfile - или его синоним readarray). Теперь мы можем проверить, существует ли в массиве ключ (имя файла) с помощью ${keepfiles[(I)filename]}, который возвращает 0, если совпадение не найдено:
% print ${keepfiles[(I)foo]}
1
% print ${keepfiles[(I)baz]}
0
%
Мы можем использовать это, чтобы создать функцию, которая возвращает true если в массиве нет совпадений для $REPLY:
% nokeep() { (( ${keepfiles[(I)$REPLY]} == 0 )); }
Наконец, мы используем эту функцию в качестве определителя в нашей команде:
% ls *(+nokeep)
baz bazfoo keepfiles.txt
или, в вашем case
% rm -- *(+nokeep)
(Вероятно, вы захотите добавить имя белого списка в белый список.)
Предполагая, что ваша оболочка bash имеет значение extglob shopt, включенное здесь, вот несколько более консервативная альтернатива:
rm !($(tr \\n \| < keep.txt))
(... сопутствующее замечательное предложение gardhead в противном случае! )
Предполагая, что в ваших файлах нет пробелов (пробелов / вкладок), перечисленных в файле с именем list, тогда вы будете делать:
find /path/to -type f \( ! -name "list" $(printf ' -a ! -name %s\n' $(< list)) \)
Просто добавьте -delete к команде выше для удаления файлов, которые не существуют в файле списка. Если у вашей находки нет опции -delete, вы можете использовать rm с -exec следующим образом:
find /path/to -type f \( ! -name "list" $(printf ' -a ! -name %s\n' $(< list)) \) -exec echo rm {} \;
Или использовать -exec с терминатором +.
find /path/to -type f \( ! -name "list" $(printf ' -a ! -name %s\n' $(< list)) \) -exec echo rm {} +
echo используется только для сушки.