Сначала протестируйте его, чтобы убедиться, что он доступен и читаем:
if [ -f "filename" ] && [ -r "filename" ]; then
var=$(<"filename")
fi
Тест -f
проверяет, ссылается ли filename
на обычный файл , а тест -r
проверяет, читается ли он вами.
Для меня самый простой и легкий для запоминания и работающий также для очень многих файлов (думал, что будет разрыв на новой строке в имени файла, но если бы у вас было это, вам пришлось бы подумать о своем списке):
cd /photo
ls -1 | grep -v -x -f nodeletelist.txt | xargs -d "\n" -P 0 rm -f
Если есть что-то еще в каталоге (подкаталоги или разные файлы, что я не предполагаю, поскольку Вы включаете свой txt в список )я бы использовал find I вместо ls(find. -maxdepth 1 -type f -name "*.jpg"
например ).
Используя rsync
и переместите файлы в фиктивный -каталог to-delete
, затем выполните безопасную -очистку:
запустить rsync
команду ниже в сухом режиме (удалить --dry-run
, если результат был хорошим)
rsync --dry-run -v -d --remove-source-files \
--exclude='*/' \
--exclude-from='/path/to/nodeletelist.txt' \
/path/to/source /path/to/source/to-delete
удалить каталог /path/to/source/to-delete
, созданныйrsync
(примечание:rsync
может создать каталог последнего уровня в месте назначения, если он не существует)и файлы были перемещены туда после двойной проверки.
rm -irv #/path/to/source/to-delete
объяснение rsync
вариантов:
# --dry-run 'dry run'
# -v 'verbose'
# -d 'override recursive'
# --remove-source-files 'sender removes synchronized files (non-dir)'
# --exclude='*/' 'exclude all directories'
# --exclude-from='...' 'exclude list of files reading from specified path'
Для указанного случая без пробелов в именах
rm $(join -v 1 <(ls *.jpg) <(sed '$ d' nodeletelist.txt))
Предполагая, что последняя строка файла nodeletelist.txt действительно читаетсяnodeletelist.txt
Если нет, то просто
rm $(join -v 1 <(ls *.jpg) nodelete.txt)
но выглядит неэлегантно...
Если zsh
является опцией, вы можете определить некоторый glob -, определяющий шелл-код, например.
% cmd() { ! grep -q $REPLY./nodeletelist.txt ; }
Затем (из каталога photo/
)
% ls
10.jpg 1.jpg 2.jpg 3.jpg 4.jpg 5.jpg 6.jpg 7.jpg 8.jpg 9.jpg nodeletelist.txt
% ls *(+cmd)
10.jpg 4.jpg 5.jpg 6.jpg 7.jpg 8.jpg 9.jpg
Выглядит нормально, давайте удалим
% rm *(+cmd)
% ls
1.jpg 2.jpg 3.jpg nodeletelist.txt
Вероятно, существует более эффективная реализация, которая сначала отображает файл в массив, а затем проверяет, является ли $REPLY
элементом массива.