Вместо того, чтобы сохранять список файлов в переменной, зацикливайте имена:
for name in TestDir/*; do
# the rest of the code
done
Чтобы проверить, встречается ли $name
в fileNames.txt
, используйтеgrep -q
:
for name in TestDir/*; do
if ! grep -qxF "$name" fileNames.txt; then
echo rm "$name"
fi
done
-F
заставляет grep
выполнять сравнение строк, а не сопоставление с регулярным выражением. С -q
мы не получаем вывода из grep
, только статус выхода, который мы можем использовать с оператором if
(true, если строка была найдена, но восклицательный знак инвертирует смысл проверки ). -x
сообщает grep
, что строка $name
должна соответствовать всей строке от начала до конца, а не только части строки.
Я защитил настоящий rm
с помощью echo
. Запустите и убедитесь, что правильные файлы удаляются.
Если имена файлов указаны без пути TestDir
, измените $name
в команде grep
на${name##*/}
:
for name in TestDir/*; do
if ! grep -qxF "${name##*/}" fileNames.txt; then
echo rm "$name"
fi
done
Это будет искать часть имени файла пути в $name
, а не полный путь, включая TestDir
.
Я не совсем понимаю, в чем ваша проблема, ваш скрипт будет перебирать только каталоги. Это обеспечивается последним /
в for dir in /var/log/fleet3/zok/*/
. Однако у вас есть очень серьезная проблема, поскольку вы неправильно поняли конструкцию $(foo)
.
$(foo)
выполнит команду foo
и вернет результат. Например:
$ echo $(pwd)
/home/terdon
Кажется, вы хотите использовать переменную, а не выполнять ее, поэтому ваша cd
команда должна быть:
cd "$dir"
А не cd $(dir)
.
Кроме того, если вы хотите удалить все подкаталоги /var/log/fleet3/zok/
, вам не нужен цикл или скрипт, вы можете просто выполнить rm -rf /var/log/fleet3/zok/*/
. Или,если вам просто по какой-то причине нужен цикл, вы можете упростить его до:
#!/bin/bash
for dir in /var/log/fleet3/zok/*/ ; do
rm -rf "$dir"/*
done