Обработка текста с несколькими разделителями в 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]}' ))