Обработка текста с несколькими разделителями в awk

У меня есть текст, который выглядит так:

      Application.||dates:[2022-11-12]|models:[MODEL1]|count:1|ids:2320 
Application.||dates:[2022-11-12]|models:[MODEL1]|count:5|ids:2320 

Я хочу номер из count:1столбцы так 1и я хочу сохранить эти числа в массиве.

      nums=($(echo -n "$grepResult" | awk -F ':' '{ print $4 }' | awk -F '|' '{ print $1 }'))

это кажется очень повторяющимся и не очень эффективным, есть идеи, как это упростить?

2 ответа

Попробуйте сед

      nums=($(sed 's/.*count://;s/|.*//' <<< "$grepResult"))

Объяснение:
есть две команды sed, разделенные ; символ.
Первая команда 's/.*count://'удалить все символы до 'count:'включая его.
Вторая команда 's/|.*//'удалить все символы, начиная с '|'включая его.
Здесь важен командный порядок.

Вы можете использовать awk один раз, установите разделитель полей на |. Затем зациклите все поля и разделите на :

Если поле начинается с countзатем напечатайте вторую часть разделенного значения.

Таким образом, часть может появиться в любом месте строки и может быть напечатана несколько раз.

      nums=($(echo -n "$grepResult" |  awk -F'|' '
{
  for(i=1; i<=NF; i++) {
    split($i, a, ":")
    if (a[1] == "count") {
      print a[2]
    }
  }
}
'))

for i in "${nums[@]}"
do
   echo "$i"
done

Выход

      1
5

Если вы хотите объединить оба значения разделения, вы можете использовать [|:]как класс символов и выведите номер поля 8 для точного соответствия, как указано в комментариях.

Обратите внимание, что он не проверяет, начинается ли он с count:

       nums=($(echo -n "$grepResult" |  awk -F '[|:]' '{print $8}'))

С gnu awkвы можете использовать группу захвата, чтобы получить немного более точное соответствие, где слева и справа может быть либо начало/конец строки, либо символ вертикальной черты. 2-я группа соответствует 1 или более цифрам:

      nums=($(echo -n "$grepResult" | awk 'match($0, /(^|\|)count:([0-9]+)(\||$)/, a) {print a[2]}' ))
Другие вопросы по тегам