искать шаблон и всегда печатать первую строку, содержащую cn

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

У dn: can может быть больше rdcPositions.

Мне нужен только dn: который имеет rdcPositions содержит acme # 6 #

Результат должен напечатать cn, а также rdcPosition

dn: cn=00fa69bd-bede-4918-a017-b59b0901bb3d,ou=Named,ou=Identities,ou=Active,o u=Vault,o=acme rdcPosition: cn=1950,ou=Entities,ou=Active,ou=Vault,o=acme#6#8946 7029901529318977152931897719249020001152931897715293191161315 2948128536 dn: cn=010903cd-e92d-4307-bffc-4921379153c0,ou=Named,ou=Identities,ou=Active,o u=Vault,o=acme rdcPosition: cn=922445,ou=Entities,ou=Active,ou=Vault,o=acme#5#42 79084890142901499714290149971924902000114290149971429023084
13 152510774136152512671665 rdcPosition: cn=311982,ou=Entities,ou=Active,ou=Vault,o=acme#6#97 26910833152812049415281204941924902000115281204941528123478
13 dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,o u=Vault,o=acme rdcPosition: cn=914570,ou=Entities,ou=Active,ou=Vault,o=acme#6#20 68839799140628466514062846651924902000014062846651406284666
13 143584728336 rdcPosition: cn=999546,ou=Entities,ou=Active,ou=Vault,o=acme#6#76 03071057140032575314003257531924902000014003257531400325754
13 144922447536 rdcPosition: cn=3513,ou=Entities,ou=Active,ou=Vault,o=acme#6#2802 0421291406284761140628476119249020000140628476114062847621314 4922459936 rdcPosition: cn=312936,ou=Entities,ou=Active,ou=Vault,o=acme#3#19 23461515144921717214492171721924902000114492171721449225081
13 

3 Solutions collect form web for “искать шаблон и всегда печатать первую строку, содержащую cn”

Кажется, что вводом является LDIF, как указано в RFC 2849 .

Я настоятельно рекомендую не использовать обычную цепочку инструментов awk / sed / grep для обработки LDIF по следующим причинам:

  • Длинные строки значений атрибута (включая dn 🙂 заключены в один пробел, указывающий продолжение строки.
  • Значения атрибута, содержащие символы не ASCII, будут закодированы в base64.

Лучшее решение – использовать достойный парсер LDIF для вашего любимого языка сценариев.

Например, для Python используйте модуль ldif в python-ldap:

Смотрите документы: ldif – парсер и генератор LDIF

Ваш желаемый результат не совсем понятен. Как далеко это вы получите:

  awk ' {while (match($0, /rdcPosition: [^ ]*acme#6#[^ ]*/)) {print substr ($0, RSTART, RLENGTH) $0 = substr ($0, RSTART + RLENGTH); } } ' file rdcPosition: cn=1950,ou=Entities,ou=Active,ou=Vault,o=acme#6#8946 rdcPosition: cn=311982,ou=Entities,ou=Active,ou=Vault,o=acme#6#97 rdcPosition: cn=914570,ou=Entities,ou=Active,ou=Vault,o=acme#6#20 rdcPosition: cn=999546,ou=Entities,ou=Active,ou=Vault,o=acme#6#76 rdcPosition: cn=3513,ou=Entities,ou=Active,ou=Vault,o=acme#6#2802 

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

 awk ' {DN = $1 FS $2 while (match($0, /rdcPosition: [^ ]*acme#6#[^ ]*/)) {print DN, substr ($0, RSTART, RLENGTH) $0 = substr ($0, RSTART + RLENGTH); } } ' file dn: cn=00fa69bd-bede-4918-a017-b59b0901bb3d,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=1950,ou=Entities,ou=Active,ou=Vault,o=acme#6#8946 dn: cn=010903cd-e92d-4307-bffc-4921379153c0,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=311982,ou=Entities,ou=Active,ou=Vault,o=acme#6#97 dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=914570,ou=Entities,ou=Active,ou=Vault,o=acme#6#20 dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=999546,ou=Entities,ou=Active,ou=Vault,o=acme#6#76 dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=3513,ou=Entities,ou=Active,ou=Vault,o=acme#6#2802 

Используя следующий скрипт sed (предполагается, что мы запускаем его с sed -n ):

 /^dn:/{ # this is a "dn" line N; # append the next line s/\n //; # remove the newline and the space x; # exchange pattern space with hold space /o=acme#6#/p; # print if pattern space contains our string d; # delete from pattern space, start next cycle } /^rdcPosition:/{ # this is a "rdcPosition" line :again; # define label for loop N; # append the next line s/\n //; # remove the newline and the space \##!b again; # if the end tag "" was not read, loop /o=acme#6#/H; # append to hold space if matching what we're looking for } ${ # at the very end of input x; # exchange pattern and hold space /o=acme#6#/p; # print if pattern space contains our string } 

Сценарий, по сути, создает строку в sed пространстве хранения (буфер общего назначения, который сохраняется между циклами). Строка начинается со строки dn а затем к ней добавляются строки rdcPosition , содержащие конкретную строку, которая нас интересует.

Всякий раз, когда обнаруживается новая строка dn или когда мы находимся в конце ввода, пробел удержания условно печатается, если он содержит нашу строку (он может не содержать ее, если ни одна из строк rdcPosition для текущей строки dn соответствует).

Тестирование это:

 $ sed -n -f script.sed file dn: cn=00fa69bd-bede-4918-a017b59b0901bb3d,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=1950,ou=Entities,ou=Active,ou=Vault,o=acme#6#894670299015293189771529318977192490200011529318977152931911613152948128536 dn: cn=010903cd-e92d-4307-bffc-4921379153c0,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=311982,ou=Entities,ou=Active,ou=Vault,o=acme#6#972691083315281204941528120494192490200011528120494152812347813 dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=914570,ou=Entities,ou=Active,ou=Vault,o=acme#6#206883979914062846651406284665192490200001406284665140628466613143584728336 rdcPosition: cn=999546,ou=Entities,ou=Active,ou=Vault,o=acme#6#760307105714003257531400325753192490200001400325753140032575413144922447536 rdcPosition: cn=3513,ou=Entities,ou=Active,ou=Vault,o=acme#6#280204212914062847611406284761192490200001406284761140628476213144922459936 

Логически эквивалентный скрипт awk который выдает тот же результат, что и код sed выше:

 /^dn:/ { if (hold ~ "o=acme#6#") print hold hold = $0; getline hold = hold substr($0, 2) next } /^rdcPosition:/ { line = $0 while (line !~ "") { getline line = line substr($0, 2) } if (line ~ "o=acme#6#") hold = hold ORS line } END { if (hold ~ "o=acme#6#") print hold } 

Вызовы substr($0, 2) пробел из прерывистых строк на входе.

Оба сценария предполагают, что строка dn разбита ровно на две строки.

  • Объединить несколько строк в строку со специальными символами
  • неверный символ '@' в выводе выражения awk
  • Группировка в строки на основе того же последнего столбца
  • Печать n-го диапазона с помощью sed
  • Пробуждение к среднему столбцу на основе ключа во 2-м столбце
  • Извлечь несколько вхождений в одну строку строки между двумя разделителями
  • Отфильтровать 2-й вхождение текста между цитатами с помощью sed?
  • Bash Разделить на файлы построчно
  • печатать строки с уникальными указанными полями
  • Как переместить каждую группу строк в новый столбец?
  • Разделить файл с разделителями на несколько файлов на основе значений в одном столбце
  • Linux и Unix - лучшая ОС в мире.