Регулярное выражение для сопоставления ошибок между двумя строками, содержащими##

Вложенные структуры данных (, такие как JSON ), должны анализироваться соответствующими инструментами (, например. json -известно здесь ), чтобы правильно извлечь информацию. Попытка работать с вложенными структурами данных только с помощью подпрограмм, поддерживающих строку -(, таких как grep/sed/awk/etc ), приведет к сбоям и ложным срабатываниям. Например, приведенный выше ответ будет работать только в том случае, если ваш JSON будет красиво -напечатан с каждым элементом JSON по одному в строке. Хотя это потерпит неудачу, если JSON будет напечатан как-то иначе (, то есть в одной строке, или с несколькими элементами в одной строке ).

Таким образом, если вы используете python, вам нужно разобрать объект, а затем извлечь необходимые данные программно (, т.е. написать скрипт на python ).

Тем не менее, есть еще один подход :для unix, есть несколько утилит, поддерживающих число или json -, разработанных для довольно легкого выполнения запроса, подобного вашему, например. jq, jtc (и многие другие ). Здесь позвольте мне показать вам решение, основанное наjtc:

Предполагая, что у вас есть следующий json:

bash $ cat file.json 
{
   "Root": [
      {
         "data": "2.71",
         "test": "e"
      },
      {
         "data": "3.14",
         "test": "pi"
      }
   ]
}
bash $ 

затем, чтобы извлечь все объекты, содержащие "test": "pi", использование jtcвыглядит следующим образом:

bash $ cat file.json | jtc -w'[test]:: [-1]'
{
   "data": "3.14",
   "test": "pi"
}
bash $ 

пояснение к обходу -путь(-w)параметры:

1. [test]::найдет все элементы типа "test": "pi"(, если их несколько)

2. [-1]повысит уровень JSON на 1 по сравнению с найденным элементом (s ).

результирующие прогулки (с )будут напечатаны.

См. jtcполное руководство пользователя здесь:https://github.com/ldn-softdev/jtc/blob/master/User%20Guide.md

2
23.07.2019, 15:15
3 ответа

Такие инструменты, как grep, сопоставляют только одну строку за раз, поэтому при использовании grepвы не можете сопоставить все это с помощью одного регулярного выражения.

Вы можете использовать такой инструмент, как sed, чтобы извлечь только часть вложенного блока, а затем передать ее в grepдля поиска интересующего вас сообщения об ошибке.

Команда /START/,/END/pв sedбудет печатать только строки между блоком, начинающимся и заканчивающимся строками, соответствующими двум регулярным выражениям. Кроме того, вы должны передать sedаргумент -n, чтобы он не печатал никаких строк по умолчанию.

Так:

$ sed -n '/^##$/,/^##$/p' mylogfile.txt |
  grep -iq '^some_error_message$'
2
27.01.2020, 21:55

Perl легко решает эту проблему с помощью своего оператора range , иногда называемого оператором flip-flop:

perl -nle 'if (/^##/.../^##/) {print if /some_error_message/i}' file

Это читает ваш файл, ища блок, который начинается и заканчивается с помощью ##, привязанного к началу строки. Затем внутри блока печатается любая строка с токеном some_error_message. В этом примере «некоторое _сообщение об ошибке _» сопоставляется без учета регистра.

2
27.01.2020, 21:55

Простая версия, простоsed(обычно вам не нужно направлять sedвывод по конвейеру, просто объединяйте команды с;):

sed '/^##$/,//!d;/some_error_message/!d'

Во-первых, мы создаем диапазон адресов от^##$(строки всего##)до пустого шаблона (, что означает :повторение последнего шаблона, таким образом, снова ##строка ). Инвертируйте совпадение с !и d, чтобы удалить все, что находится за пределами диапазона.

Во-вторых, dудалить все строки, не(!)содержащие some_error_message.

1
27.01.2020, 21:55

Теги

Похожие вопросы