
Я создал скрипт, который использует for loop
для цикла по скрипту IBM, чтобы получить размер каталогов. Затем скрипт выводит размер каталога и путь к каналу Slack для удобства просмотра. Программа работает, но вывод скрипта IBM большой и требует форматирования, чтобы его было легко читать в Slack. Поэтому мне нужно собрать два фрагмента информации, которые будут переданы в две отдельные переменные, а переменные будут использоваться для создания сообщения Slack. Мой скрипт выглядит так:
SIZE () {
for dir in /path/to/dir/*
do
cd /usr/lpp/mmfs/samples/ilm/
SLACKMESSAGE=$(./mmpolicy-du.sample "$dir" -t /mmfs1/.policytmp -g /mmfs1/.policytmp/ -N all -v -h)
SLACK
done
}
Так же как /path/to/dir/*
и родительский каталог, и скрипт IBM ./mmpolicy-du.sample "$dir" -t /mmfs1/.policytmp -g /mmfs1/.policytmp/ -N all -v -h
будет проходить по всем дочерним каталогам (на один уровень глубже) и получать их размер. Вывод выглядит так:
[I] 2018-05-31@16:32:55.798 Policy execution. 0 files dispatched.
[I] 2018-05-31@16:32:55.804 Policy execution. 0 files dispatched.
File system scan complete.
534.5M total
mmapplypolicy du for /path/to/directory/SPI/ complete at Thu May 31 17:32:55 2018
Это не самый чистый вывод, поэтому я хотел бы передать размер каталога в приведенном выше примере 534.5M
в переменную с именем SIZE
, а SPI
в другую переменную с именем PROJECT
. Конечно, поскольку это цикл, переменная SIZE
и PROJECT
будет изменяться в каждом каталоге внутри приведенного выше примера /path/to/dir/
. Функция Slack, которая вызывается в моей приведенной выше функции, будет использовать эти две переменные. Я изо всех сил пытаюсь понять, как поместить эти две переменные в переменные. У кого-нибудь есть решение? Спасибо!
решение1
Чтобы сделать это за один раз:
eval "$(yourscript | awk -v q=\' '
$1 ~ /^[[:digit:]]+(\.[[:digit:]]+)?[MGT]$/ {
print "SIZE=" $1
}
match($0, /[[:upper:]]{3}/) {
print "PROJECT="q substr($0, RSTART, RLENGTH) q
}')"
Обратите внимание, что некоторые awk
реализации, такие как nawk
или Solaris, mawk
или более старые версии gawk
не поддерживают операторы интервала регулярного выражения {x,y}
/ {x}
(в случае более старых (и не древних) версий gawk
вы можете запустить его POSIXLY_CORRECT=anything
в среде, чтобы он поддерживал их), хотя он является стандартом уже более 25 лет. В этих случаях вам нужно будет заменить [[:upper:]]{3}
на [[:upper:]][[:upper:]][[:upper:]]
.
решение2
Я очень сомневаюсь, что это то, что вам нужно, но это дословный ответ на ваш текущий вопрос.
Первая часть (предполагается, что это GNU grep
или совместимая версия):
project="$(yourscript|grep -oE '[[:upper:]]{3}')"
Вторая часть:
size="$(yourscript|grep -oE '[[:digit:]]+(\.[[:digit:]]+)?[MGT]')"
В совокупности проще запустить скрипт один раз, сохранить вывод, а затем выполнить grep и назначить сохраненный вывод:
output="$(script)"
size="$(printf '%s\n' "$output"|grep -oE '[[:digit:]]+(\.[[:digit:]]+)?[MGT]')"
project="$(printf '%s\n' "$output"|grep -oE '[[:upper:]]{3}')"
Некоторые пояснения
grep -o
- возвращает только обработанный объект, а не всю строку
-E
- Расширенное регулярное выражение
[[:upper:]]
- соответствует только заглавным буквам ([AZ], но независимо от локали)
{3}
- ограничивает соответствие ровно 3 последовательными символами
[[:digit:]]
- соответствует цифрам ([0-9], снова без учета локали)
+
- соответствует 1 или более раз
\.
- соответствует точке
(...)?
- соответствует 0 или 1 раз - это гарантирует, что числа без десятичной точки также могут быть захвачены
[xy]
- соответствует ровно одному из элементов x или y.