Официальная возможность получить лицензионный софт бесплатно.
Giveaway of the Day
Это не реклама!

Щелкните для получения прогноза по Биробиджану


четверг, 16 июля 2015 г.

bash: получить список файлов в переменную, работа с массивами

Не самая редкая задача: обработать группу файлов, но при этом из список должен быть считан в переменную. Для чего? Ну, например, у меня есть каталог, в котором файлы с разными расширениями, причем над одними надо выполнять какую-то операцию, над другими нет, в зависимости не только от расширения, но и от имени или от погоды в Африке.

Рецепт:

переменная_скрипта=( шаблон_имён_файлов )

Дальше - согласно ABSG Ch. 27 "Arrays" и подробнее на стр. 415-416 (если у кого есть ссылка на официальный Advanced Bash Scripting Guide 2014 или 2015 года, буду признателен)
Количество элементов в массиве: ${#имя[@]}
Длина конкретного элемента: ${#имя[номер]}



Из моего реального массива:

$  ls -la
-rwxr-xr-x  1 root root 1571 июля  16 09:55 backup_samba_rsync.sh
-rwxr-xr-x  1 root root  210 июня  29 09:10 fix-rights-subshares.sh
-rwxr-xr--  1 root root 1649 марта 20  2013 mkgroupdir
-rwxr-xr-x  1 root root  378 июля   3 11:10 mkhomedir.sh
-rwxr-xr-x  1 root root 6867 сент. 12  2014 mslink.sh
-rwxr-xr-x  1 root root 6867 сент.  5  2013 mslink.sh.org
-rw-r--r--  1 root root  171 сент. 12  2014 printer28.lnk
-rwxr-xr-x  1 root root 2685 дек.  17  2014 purge-old-scans.sh
-rwxr-xr-x  1 root root  841 сент.  1  2014 restore-homes-rights
-rwxr-xr-x  1 root root 1899 дек.  14  2014 restore-secret-new.sh
-rwxr-xr-x  1 root root  672 сент. 24  2013 samba-purge-trash.sh
-rwxr--r--  1 root root   58 сент. 29  2014 scan_auth.conf
-rwxr-xr-x  1 root root   65 нояб. 16  2012 smb-restart
-rwxr-xr-x  1 root root  350 дек.  31  2013 smb-set-group-rw.sh
-rwxr-xr-x  1 root root  102 июля  16 11:32 test line.sh 
-rwxr-xr-x  1 root root  102 июля  16 09:32 testline.sh

$ filetest=( *.sh )

$ echo ${#filetest[@]}
10

$ echo ${filetest}
backup_samba_rsync.sh

$ echo ${filetest[*]}
backup_samba_rsync.sh fix-rights-subshares.sh mkhomedir.sh mslink.sh purge-old-scans.sh restore-secret-new.sh samba-purge-trash.sh smb-set-group-rw.sh test line.sh testline.sh  

$ echo ${filetest[@]}
backup_samba_rsync.sh fix-rights-subshares.sh mkhomedir.sh mslink.sh purge-old-scans.sh restore-secret-new.sh samba-purge-trash.sh smb-set-group-rw.sh test line.sh testline.sh

$ echo ${filetest[4]}
purge-old-scans.sh

$ echo ${filetest[8]}
test line.sh

Нумерация элементов массива, как видно, начинается с нуля.
Обратите внимание на 8 элемент - в имени файла есть пробел, и эта ситуация обрабатывается нормально.

Для проверки, а есть ли вообще такие файлы, попало ли что-нибудь в массив, можно выполнить

if [ -e ${filetest[0]} ]

Если в переменную ничего не записалось, то вернется шаблон, например *.sh, а проверка -е не умеет работать с шаблонами и установит ненулевой код завершения.

Казалось бы, для чего такие сложности, когда можно написать что-то вроде for a in ( *.sh ) do... и радоваться жизни. Или, как я писал в 2010 про unmo3, в скобках перечислить несколько расширений.

Вопрос в том, что полученный массив можно использовать где угодно и как угодно, например, пройтись по нему sed-ом и что-то удалить или заменить. Можно добавить элемент и т.д. В общем, штука нужная и удобная.

Из реальной жизни. Читаю из файла конфигурации строку со списком параметров, например, списком расширений файлов, которые мне надо обрабатывать в скрипте. Скрипт заранее не знает, что там в этом конфиге, сколько элементов и т.д. Но строка считана в массив и я с ней делаю, что хочу. Например, организовываю цикл с конца, а не с начала.

Комментариев нет:

Отправить комментарий

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