Учитывая, что ваши имена файлов в формате file.00064.name.99999.end
, нам сначала нужно обрезать все, кроме нашего номера. Мы будем использовать for
цикл, чтобы сделать это.
Мы также должны указать оболочке Bash использовать основание 10, потому что арифметика Bash будет обрабатывать их числа, начинающиеся с 0, как основание 8, что приведет нас к путанице.
В качестве скрипта, запускаемого в каталоге, содержащем файлы, используйте:
#!/bin/bash
for f in ./*
do
if [[ -f "$f" ]]; then
file="${f%.*}"
if [[ $((10#${file##*.} % 12)) -ne 0 ]]; then
rm "$f"
fi
else
echo "$f is not a file, skipping."
fi
done
Или вы можете использовать эту очень длинную уродливую команду, чтобы сделать то же самое:
for f in ./* ; do if [[ -f "$f" ]]; then file="${f%.*}"; if [[ $((10#${file##*.} % 12)) -ne 0 ]]; then rm "$f"; fi; else echo "$f is not a file, skipping."; fi; done
Чтобы объяснить все части:
for f in ./*
означает для всего в текущем каталоге, do .... Это устанавливает каждый файл или каталог, найденный как переменная $ f.
if [[ -f "$f" ]]
проверяет, является ли найденный элемент файлом, в противном случае мы переходим к echo "$f is not...
части, что означает, что мы не начинаем удаление каталогов случайно.
file="${f%.*}"
устанавливает переменную $ file в качестве имени файла, обрезая все, что идет после последнего .
.
if [[ $((10#${file##*.} % 12)) -eq 0 ]]
это где основная арифметика вступает в силу. ${file##*.}
Обрезает все до последнего .
в нашем имени файла без расширения. $(( $num % $num2 ))
является синтаксисом арифметики Bash для использования операции по модулю, а 10#
в начале Bash указывает Bash использовать 10, чтобы справиться с этими надоедливыми ведущими нулями. $((10#${file##*.} % 12))
затем оставляет нам остаток от нашего имени файла, разделенный на 12. -ne 0
проверяет, не равен ли остаток «нулю».
- Если остаток не равен 0, то файл удаляется с
rm
командой, вы можете заменить rm
с echo
при первом запуске этого, чтобы убедиться , что вы получите ожидаемые файлы для удаления.
Это решение не является рекурсивным, это означает, что оно будет обрабатывать только файлы в текущем каталоге и не попадать ни в какие подкаталоги.
if
Заявление с echo
командой , чтобы предупредить о каталогах не действительно необходимо , так как rm
на его собственном будет жаловаться каталогами, а не удалять их, так:
#!/bin/bash
for f in ./*
do
file="${f%.*}"
if [[ $((10#${file##*.} % 12)) -ne 0 ]]; then
rm "$f"
fi
done
Или
for f in ./* ; do file="${f%.*}"; if [[ $((10#${file##*.} % 12)) -ne 0 ]]; then rm "$f"; fi; done
Будет работать правильно тоже.