Как найти строку после регулярного выражения в одной строке текста?

У меня есть текстовый файл, содержащий очень длинную строку данных JSON, и мне нужно извлечь значение некоторого поля. Я понимаю, что самый простой способ сделать это – использовать jq или grep -o ; однако я нахожусь на фирменной машине, поэтому я не могу установить jq , и мы используем версию Solaris, где grep не имеет опции -o . В настоящее время я использую команду:

 cat json.file | tr "," "\n" | awk '/customfield_10701/ { print $0 }' | tr '"' "\n" | awk 'NR==4' 

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

Пример json.file :

 ... jshdgfjhsdgfjh,"customfield_10701":"Some Branch","customfield_10702ksghdkfsdkfjkj ... 

С моей текущей командой я получаю:

 Some Branch 

(это то, что я хочу).

Если вы уверены, что нет никаких символов в данных, которые вы ищете, и если в файле есть только одна строка, содержащая запись «customfield_10701», тогда

 sed -n 's/.*"customfield_10701":"\([^"]*\)".*/\1/p' 

например,

 $ cat x ... jshdgfjhsdgfjh,"customfield_10701":"Some Branch","customfield_10702ksghdkfsdkfjkj ... $ sed -n 's/.*"customfield_10701":"\([^"]*\)".*/\1/p' x Some Branch 

Вам не нужно использовать tr для преобразования запятых в новые строки. А потом снова. Вы можете указать awk использовать запятую в качестве разделителя входных данных ( RS ).

 awk -F':' -v RS=',' '/customfield_10701/ { gsub(/"/,"",$2); print $2 }' json.file 

gsub() используется для удаления двойных кавычек (если они есть) из поля 2.

Если необходимо, вы также можете использовать gsub() для удаления верхних и конечных пробелов и вкладок:

 awk -F':' -v RS=',' '/customfield_10701/ { gsub(/"|^[[:blank:]]+|[[:blank:]]+$/,"",$2); print $2 }' json.file 

Обратите внимание, что селектор выходной записи ( ORS ) не изменяется автоматически при изменении RS, он остается по умолчанию (новая строка), если вы не установите его (например, с -v ORS=',' ).

Следующий тест работает для меня с использованием встроенного regex-сервера bash 3 и не требует внешних программ:

 json='"jshdgfjhsdgfjh,"customfield_10701":"Some Branch","customfield_10702ksghdkfsdkfjkj"' regex_hint=customfield_10701 [[ $json =~ $regex_hint\":\"(.+)\", ]] && printf '%s\n' "${BASH_REMATCH[1]}" 

Печатные издания: некоторые отделения

Регулярное выражение между '()' является «группой захвата 1», которое сохраняется в «$ {BASH_REMATCH 1 }»

Обратите внимание, что bash builtin поддерживает расширенные регулярные выражения POSIX, а не более известные регулярные выражения Perl Compatible Regular Expressions