З огляду на те, що ваші імена файлів у форматі file.00064.name.99999.end
, спершу потрібно обрізати все, крім нашої кількості. Для цього ми використаємо for
цикл.
Нам також потрібно сказати оболонці Bash використовувати базу 10, тому що арифметика Баша буде вважати їх числами, починаючи з 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 ./*
означає для всього, що знаходиться в поточному каталозі, зробіть .... Тут встановлюється кожен файл чи каталог, що знайдеться як змінна $ f.
if [[ -f "$f" ]]
перевіряє, чи є знайдений елемент файлом, якщо не переходимо до echo "$f is not...
частини, це означає, що ми не починаємо видаляти каталоги випадково.
file="${f%.*}"
встановлює змінну файлу $ як назву файлу, що обрізає все, що настає після останнього .
.
if [[ $((10#${file##*.} % 12)) -eq 0 ]]
це головна арифметика. ${file##*.}
Обрізає все до останнього .
у нашому файлі без розширення. $(( $num % $num2 ))
є синтаксисом для арифметики Bash для використання модульної операції, 10#
на початку вказує Bash використовувати базу 10, щоб мати справу з тими неприємними провідними 0. $((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
Також буде працювати правильно.