Найти строку в одном разделе файла с несколькими разделами

Как sed / awk для строки, содержащейся в другой строке.

TESTVAR=' { icon : "icons/773_l.png", id : 80, initialState : true, isPng : false, label : "Imagery", opacity : 1, requestType : "UUID", version : 79 } , { icon : "thisicon", id : 8080, initialState : false, isPng : true, label : "Boundaries", opacity : 1, requestType : "NothingSpecial", version : 8 } 

Мне нужно выбрать version : 79 для объекта, который содержит requestType : "UUID" . Как выбрать все внутри первого блока, затем выбрать версию и просто вернуть команду 79 . Я пытался в течение некоторого времени, но не знаю, как выбрать только все между первым {} . Как только у меня это получилось, мне просто нужно будет получить номер после version :

Я думал, что это сработает, но у него нет awk '/\{/{f=1;next}/\}/{f=0}f' test.txt

Кроме того, заказ не гарантируется. Поэтому мне действительно нужно выбрать все внутри { и } содержащее «UUID». Затем выберите version : \([0-9]+\)

Это близко, но слишком жадно: sed -e 's/{\(.*UUID.*\)}/\1/' test.txt

3 Solutions collect form web for “Найти строку в одном разделе файла с несколькими разделами”

Во-первых, что приходит мне в голову: ни sed, ни awk:

 $ tr -d '\n' < file | grep -Po 'requestType : "UUID"\K.*? version : \K[0-9]*' 79 

Вероятно, это можно сделать проще, особенно если вы можете гарантировать, что «версия» появится сразу после «requestType».

В случае, если version не должна идти после requested Type вещи немного сложнее:

 $ tr -d '\n' < file | grep -Po '{.[^}]*?requestType : "UUID".*?}' | grep -Po 'version : \K[0-9]*' 79 

Если есть больше разделов, которые могут совпадать со всеми, они будут напечатаны:

 $ cat file TESTVAR=' { icon : "icons/773_l.png", id : 80, initialState : true, isPng : false, label : "Imagery", opacity : 1, version : 79, requestType : "UUID" } , { icon : "thisicon", id : 8080, initialState : false, isPng : true, label : "Boundaries", opacity : 1, requestType : "NothingSpecial", version : 8 } , { icon : "icons/773_l.png", id : 80, initialState : true, isPng : false, label : "Imagery", opacity : 1, requestType : "UUID", version : 87 } , { icon : "icons/773_l.png", id : 80, version : 17, initialState : true, isPng : false, label : "Imagery", opacity : 1, requestType : "UUID" } , { icon : "thisicon", id : 8080, requestType : "NothingSpecial", initialState : false, label : "Boundaries", opacity : 1, version : 18, isPng : true } $ tr -d '\n' < file | grep -Po '{.[^}]*?requestType : "UUID".*?}' | grep -Po 'version : \K[0-9]*' 79 87 17 

awk позволяет определить разделитель записи, поэтому вместо новой строки (каждая строка – это запись) используйте «} \ n» в качестве конца записи:

 echo "$TESTVAR" | gawk -v RS="}\n" ' /requestType : "UUID"/ && match($0, /version : ([0-9]+)/, m) {print m[1]} ' 
 79 

Это особенность GNU awk для функции match ().


Жаль, что это недействительно JSON. Затем вы можете использовать парсер JSON:

 jq '(.[] | select(.requestType == "UUID")).version' <<JSON [ { "icon" : "icons/773_l.png", "id" : 80, "initialState" : true, "isPng" : false, "label" : "Imagery", "opacity" : 1, "requestType" : "UUID", "version" : 79 } , { "icon" : "thisicon", "id" : 8080, "initialState" : false, "isPng" : true, "label" : "Boundaries", "opacity" : 1, "requestType" : "NothingSpecial", "version" : 8 } ] JSON 

Вот один из способов сделать это с помощью sed :

 $ sed -rn '/\{/{:a;N;/\}/{/requestType : "UUID"/s/.*version : ([0-9]+).*/\1/p;d};ba}' <<< "$TESTVAR" 79 $ 

Это зависит от https://stackoverflow.com/a/18046021/2113226 для ваших данных.


Вы упомянули, что это структура данных javascript, поэтому я думаю, что самый надежный метод для ее анализа будет использовать javascript. Я установил Node.js для этого, но я предполагаю, что любой интерпретатор javascript в командной строке должен иметь возможность сделать что-то вроде этого:

 $ echo "arr=[$TESTVAR]; console.log(arr.filter(function(elem) { return elem.requestType === \"UUID\"; })[0].version)" | node 79 $ 

отказ

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

  • Как комментировать snmpmibd и snmpd в rc.tcpip в AIX с помощью sed?
  • Как правильно избежать этой длинной команды su + sed?
  • Вытягивание IP-адреса из команды ping с помощью sed?
  • как заменить выражение sed / perl (изменить и распечатать только согласованную строку) с выражением python?
  • Как вставить первую строку одного файла в первую строку другого?
  • Различное поведение sed относительно массива и строки при наличии обратных косых черт
  • Как удалить строки, содержащие некоторые имена в одном столбце в файлах txt
  • Найдите строку с двумя последними символами в виде числовых
  • Добавить строку во многие файлы
  • Как удалить строки, где данная часть строки содержит более 100 символов?
  • Мне нужно удалить. в моих данных
  • Linux и Unix - лучшая ОС в мире.