удалить файл, но исключить все файлы в списке

Все мои разделы 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)?

1
задан 29 September 2016 в 10:03

5 ответов

Этот скрипт 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], чтобы они оба были в списке и сохраняли их в одном каталоге.

10
ответ дан 23 May 2018 в 05:40
  • 1
    Я изменил свой код, чтобы вместо [O1] вместо O (n) искать вторую часть. – David Foerster 28 September 2016 в 18:03
  • 2
    спасибо за вашу помощь, я, как правило, парень из окна, но шлейфы питона тоже будут крутыми =) – stefan83 29 September 2016 в 08:34
  • 3
    @ stefan83: Python работает так же хорошо и в Windows. – David Foerster 13 October 2016 в 11:41

Вот один лайнер:

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 запрашивать подтверждение перед выполнением.
2
ответ дан 23 May 2018 в 05:40
  • 1
    THX для вашей помощи, теперь у меня есть мое решение! – stefan83 29 September 2016 в 08:35

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)

(Вероятно, вы захотите добавить имя белого списка в белый список.)

1
ответ дан 23 May 2018 в 05:40

Предполагая, что ваша оболочка bash имеет значение extglob shopt, включенное здесь, вот несколько более консервативная альтернатива:

rm !($(tr \\n \| < keep.txt))

(... сопутствующее замечательное предложение gardhead в противном случае! )

0
ответ дан 23 May 2018 в 05:40

Предполагая, что в ваших файлах нет пробелов (пробелов / вкладок), перечисленных в файле с именем 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 используется только для сушки.

0
ответ дан 23 May 2018 в 05:40

Другие вопросы по тегам:

Похожие вопросы: