Скрипт для прокрутки папок с числовыми именами

Я работаю над скриптом bash для сжатия изображений в папках WordPress. Структура папки wordpress выглядит следующим образом:

> wp-content/uploads/2014/01/filename.jpg > wp-content/uploads/2014/02/filename.jpg > wp-content/uploads/2014/03/filename.jpg > wp-content/uploads/2014/04/filename.jpg > > ie wp-content/uploads/YEAR/MONTH/filename.jpg 

В папке uploads у меня есть несколько других папок (которые были созданы, когда были установлены плагины), поэтому я пытаюсь прокрутить папки только с числовыми именами, а затем сжать изображения. Вот что я имею до сих пор:

 DIR_UPLOADS=/home/html/wp-content/uploads/ cd ${DIR_UPLOADS} for d in *; do # First level ie 2014, 2013 folders. regx='^[0-9]+$' # Regular Expression to check for numerics. if [[$d =~ $regx]]; then # Check if folder name is numeric. #echo "error: Not a number" >&2; exit 1 cd $d for z in *; do # Second level ie the months folders 01, 02 etc. cd $z for x in *; do # Third level the actual file. echo 'Compress Image' done done fi done 

Я пытаюсь использовать reg ex для обнаружения числовых папок, это не совсем правильно, но я думаю, что я близок.

Вы можете использовать расширенный бэбинг bash для этого:

 shopt -s extglob DIR_UPLOADS=/home/html/wp-content/uploads/ cd ${DIR_UPLOADS} for dir in $PWD/+([0-9])/+([0-9]); do cd "$dir" && for file in *; do echo 'Compress Image' done done 

На странице руководства:

 +(pattern-list) Matches one or more occurrences of the given patterns 

Таким образом, размещение диапазона номеров внутри будет соответствовать файлам / каталогам. Добавление условия && гарантирует, что вы только сжимаете изображения, если совпадение является каталогом (и что вам действительно удалось ввести его).

Без расширенного globbing вы могли бы просто сделать [1-2][0-9][0-9][0-9]/[0-1][0-9] . Это лучше, чем попытка расширения брекета, поскольку вы не станете пытаться вводить каталоги за каждый год / месяц, даже если у вас нет изображений с этого момента.

Я думаю, что сделал бы это с помощью find но только для того, чтобы ответить на ваши вопросы о сценариях. Я немного изменил ваш пример.

 #!/bin/bash for d in *; do # First level ie 2014, 2013 folders. regx='^[0-9]+$' # Regular Expression to check for numerics. echo "dir: $d" if [[ $d =~ $regx ]]; then # Check if folder name is numeric. echo "found num: $d" pushd $d >& /dev/null for z in *; do # Second level ie the months folders 01, 02 etc. pushd $z >& /dev/null for x in *; do # Third level the actual file. echo "Compressing Image: $x" done popd >& /dev/null done popd >& /dev/null fi done 

Твой подход казался прекрасным. Я думаю, что частью вашей проблемы было использование cd . Вам нужно вернуться к уровням каталогов, когда вы «ходите» по дереву каталогов. Обычно я использую pushd и popd , поскольку я добавил их к вашему примеру.

пример

Теперь, когда я запускаю это в моем каталоге загрузки WordPress:

 $ pwd /var/www/html/apps/wordpress/wp-content/uploads 

Пробный пробег:

 $ ./asc.bash | head -15 dir: 2009 found num: 2009 Compressing Image: GURULABS-RPM-GUIDE-v1.0.pdf Compressing Image: How_to_create_an_RPM_package.mht Compressing Image: ss_mtr_1-150x150.png Compressing Image: ss_mtr_1-300x146.png Compressing Image: ss_mtr_1.png Compressing Image: ss_mtr_2-150x150.png Compressing Image: ss_mtr_2-300x115.png Compressing Image: ss_mtr_2.png Compressing Image: ss_mtr_3-150x150.png Compressing Image: ss_mtr_3-300x117.png Compressing Image: ss_mtr_3.png Compressing Image: ss1_trac_gitplugin-1024x262.png Compressing Image: ss1_trac_gitplugin-150x150.png 

улучшения

Я бы добавил несколько тестов, прежде чем просматривать данный месяц в тех случаях, когда каталог этого месяца пуст. В противном случае вы получите следующее:

 Compressing Image: * Compressing Image: * Compressing Image: * 

Прогулка по дереву каталогов, подобному этому, может быть сложной задачей. Поскольку структура каталогов достаточно структурирована, почему бы не пройти его так:

 for dir in 20*/*; do echo "$dir" for files in $dir/*; do if [ -e $dir/$files ]; then echo "$dir/$files: ..compress.." fi done done 

Или вот так:

 for year in $(printf '%4d\n' {2000..2014}); do echo "$year" for mnth in $(printf '%02d\n' {00..12}); do if [ -e $year/$mnth ]; then echo "$mnth" fi done done