Использование sed / awk для ограничения / разбора вывода LDAP DN - PullRequest
1 голос
/ 28 декабря 2011

У меня есть большой список DN LDAP, которые связаны с тем, что их не удалось импортировать в мое приложение.Мне нужно запросить их по моей внутренней базе данных на основе очень специфической части CN, но я не совсем уверен, как можно ограничить строки очень специфическим значением, которое не обязательно находится в той же позициикаждый раз.

Используя следующую команду bash:

grep 'Failed to process entry' /var/log/tomcat6/catalina.out | awk '{print substr($0, index($0,$14))}'

Я могу вернуть список DN, похожий на: (извините за отредактированный характер, диктует безопасность)

"cn=[Last Name] [Optional Middle Initial or Suffix] [First Name] [User name],ou=[value],ou=[value],o=[value],c=[value]".

Значение CN может сбивать с толку, так как порядок фамилии, имени, среднего имени, префикса или суффикса может отображаться в любом порядке, если значения существуют, но одно остается неизменным, имя пользователя всегда является последним полем вcn (за которым следует ",", затем первый из множества потенциальных подразделений).Мне нужно разобрать это имя пользователя для запроса, предпочтительно в список через запятую, чтобы его можно было легко копировать и вставлять для использования в запросе SQL IN () или использования в скрипте bash.В качестве примера представьте следующий короткий список сокращенных DN, показывающий только значение CN (так как остальная часть DN не имеет значения):

"cn=Doe Jr. John john.doe,ou=...".
"cn=Doe A. Jane jane.a.doe,ou=...".
"cn=Smith Bob J bsmith,ou=...".
"cn=Powers Richard richard.powers1,ou=...".

Я хотел бы получить список csv, который выглядиткак:

john.doe,jane.a.doe,bsmith,richard.powers1

Может ли сочетание awk и / или sed выполнить это?

Ответы [ 5 ]

1 голос
/ 28 декабря 2011
sed -e 's/"^[^,]* \([^ ,]*\),.*/\1/'

проанализирует часть имени пользователя общего имени и изолирует имя пользователя. Продолжайте с

| tr '\n' , | sed -e 's/,$/\n/'

для преобразования формата имени пользователя по одной строке в разделенную запятыми форму.

0 голосов
/ 10 марта 2013

Прошло уже больше года с тех пор, как на эту тему была опубликована идея, но он хотел найти место, на которое можно сослаться в будущем, когда этот класс вопросов появится снова. Кроме того, я не видел похожего ответа.

Из представленной структуры данных я понимаю, что мы можем убрать все после первой запятой, оставив нам истинный CN, а не DN, начинающийся с CN. В CN мы убираем все до и включая последний пробел. Это оставит нас с именем пользователя.

awk -F ',' / ^ cn = / {print $ 1} 'ldapfile | awk '{print $ NF}' >> имена пользователей

Передавая файл ldap в awk, с разделителем полей, установленным на запятую, и строкой соответствия, установленной на cn = в начале строки, мы печатаем все до первой запятой. Затем мы передаем эти выходные данные в awk с разделителем полей по умолчанию и печатаем только последнее поле, в результате чего получаем только имя пользователя. Мы перенаправляем и добавляем это в файл в текущем каталоге с именем usernames, и в итоге получаем одно имя пользователя на строку.

Чтобы преобразовать это в одну строку имен пользователей через запятую, мы изменим последнюю команду печати на printf, исключив символ новой строки \ n, но добавив запятую.

awk -F ',' / ^ cn = / {print $ 1} 'ldapfile | awk '{printf $ NF ","}' >> usernames

Это оставляет единственную строку в файле с запятой, но поскольку она предназначена только для вырезания и вставки, просто не обрезайте последний символ. :)

0 голосов
/ 28 декабря 2011

Решение регулярных выражений Perl, которое я считаю более читабельным, чем альтернативы, на случай, если вам интересно:

perl -ne 'print "$1," if /(([[:alnum:]]|[[:punct:]])+),ou/' input.txt

Печатает строку, предшествующую 'ou', принимает буквенно-цифровые символы и символы пунктуации (но без пробелов, поэтомуостанавливается на имени пользователя).

Вывод:

john.doe,jane.a.doe,bsmith,
0 голосов
/ 28 декабря 2011

Дан файл "Document1.txt", содержащий

cn = Смит Джейн batty.cow, ou = ou1_value, ou = oun_value, o = o_value, c = c_value

cn = Marley Bob reggae.boy, ou = ou1_value, ou = oun_value, o = o_value, c = c_value

cn = Клинтон Дж. Билл, бывший президент, ou = ou1_value, ou = oun_value, o = o_value, c = c_value

вы можете сделать

cat Document1.txt | sed -e "s/^cn=.* \([A-Za-z0-9._]*\),ou=.*/\1/p"

который тебя достает

batty.cow

reggae.boy

ex.president

с использованием tr для перевода символа конца строки

cat Document1.txt | sed -n "s/^cn=.* \([A-Za-z0-9._]*\),ou=.*/\1/p" | tr '\n' ',' 

производит

batty.cow, reggae.boy, ex.president,

вам нужно иметь дело с последней запятой

но если вы хотите это в базе данных, скажите, например, oracle, скрипт, содержащий:

#!/bin/bash
doc=$1
cat ${doc} | sed -e "s/^cn=.* \([A-Za-z0-9._]*\),ou=.*/\1/p" | while read username
    do
    sqlplus -s username/password@instance <<+++ insert into mytable (user_name) values ('${username}'\;)
    exit
    +++
done

N.B. A-Za-z0-9._ в выражении sed - это все типы символов, которые вы ожидаете в имени пользователя - вам, возможно, придется поиграть с этим.

Предостережение - я не проверял последний бит со вставкой базы данных в него!

0 голосов
/ 28 декабря 2011

Вот один быстрый и грязный способ сделать это -

awk -v FS="[\"=,]" '{ print $3}' file | awk -v ORS="," '{print $NF}' | sed 's/,$//'

Тест:

[jaypal:~/Temp] cat ff
"cn=Doe Jr. John john.doe,ou=...".
"cn=Doe A. Jane jane.a.doe,ou=...".
"cn=Smith Bob J bsmith,ou=...".
"cn=Powers Richard richard.powers1,ou=...".
[jaypal:~/Temp] awk -v FS="[\"=,]" '{ print $3}' ff | awk -v ORS="," '{print $NF}' | sed 's/,$//'
john.doe,jane.a.doe,bsmith,richard.powers1

OR

Если у вас есть gawk, тогда

gawk '{ print gensub(/.* (.*[^,]),.*/,"\\1","$0")}' filename | sed ':a;{N;s/\n/,/}; ba'

Тест:

[jaypal:~/Temp] gawk '{ print gensub(/.* (.*[^,]),.*/,"\\1","$0")}' ff | sed ':a;{N;s/\n/,/}; ba'
john.doe,jane.a.doe,bsmith,richard.powers1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...