Grep 3 заглавных букв и цифр в две переменные

Grep 3 заглавных букв и цифр в две переменные

Я создал скрипт, который использует 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.

Связанный контент