2 votes

Utilisation de bash pour analyser la sortie de ldapsearch

J'ai récemment écrit un bash script qui devait analyser la sortie des résultats de ldapsearch. Le script fonctionne, mais j'imagine qu'il existe un moyen plus efficace d'accomplir cette tâche.

Le script exécute une commande ldapsearch, qui produit plusieurs enregistrements dans un format multiligne. Chaque enregistrement est séparé par une ligne blanche. Ce que j'ai fini par faire est le suivant :

  1. ajouter un caractère de délimitation à la fin de chaque ligne
  2. Ajouter la chaîne 'DELIM' aux lignes vides
  3. rogné toutes les nouvelles lignes
  4. Remplacement de 'DELIM' par une nouvelle ligne

Cela a pour effet de transformer la sortie multiligne de ldapsearch en plusieurs lignes de valeurs séparées et délimitées. J'utilise ensuite cut deux fois pour analyser les lignes (une fois pour séparer le délimiteur, et une autre fois pour renvoyer la sortie du résultat de ldap).

Voici le code :

while IFS= read -r line ; do
 dn=$(echo "$line" | cut -d '#' -f 1 | cut -d " " -f 2)
 uid=$(echo "$line" | cut -d '#' -f 2 | cut -d " " -f 2)
 uidNumber=$(echo "$line" | cut -d '#' -f 3 | cut -d " " -f 2)
 gidNumber=$(echo "$line" | cut -d '#' -f 4 | cut -d " " -f 2)

 # Code emitted since it's not relevant

done < <(ldapsearch -x -H "$ldap_server" -D 'cn=Directory Manager' -w $ds_password -b "$searchbase" -LLL uid uidNumber gidNumber | sed 's/$/#/g' | sed 's/^#$/DELIM/g' | tr -d '\n' | sed 's/DELIM/\n/g')

La sortie de la commande ldapsearch est la suivante

dn: uid=userone,ou=People,dc=team,dc=company,dc=local
uid: userone
uidNumber: 5000
gidNumber: 5000

dn: uid=usertwo,ou=People,dc=team,dc=company,dc=local
uid: usertwo
uidNumber: 5001
gidNumber: 5001

Existe-t-il un moyen plus efficace d'y parvenir ? Plus précisément, une méthode qui n'utilise pas autant de tuyaux ?

2voto

Jotne Points 15088

Vous pouvez jouer avec awk

ldap search | awk '$1=$1' RS= ORS='\n' OFS='#'
dn: uid=userone,ou=People,dc=team,dc=company,dc=local#uid: userone#uidNumber: 5000#gidNumber: 5000
dn: uid=usertwo,ou=People,dc=team,dc=company,dc=local#uid: usertwo#uidNumber: 5001#gidNumber: 5001

RS= Mettre le sélecteur d'enregistrement sur rien (mettra awk en mode bloc) (normalement chaque ligne)
ORS='\n' Mettre le sélecteur d'enregistrement de sortie sur une nouvelle ligne
OFS='#' Définir le séparateur de champ de sortie à #.
$1=$1 recréer la ligne et l'imprimer.

Cela peut être plus sûr à utiliser :

awk '{$1=$1}1' RS= ORS='\n' OFS='#'

1voto

markp Points 2561

Hypothèses :

  • les données ldapsearch ne contiennent pas d'espace(s) blanc(s)
  • Le reformatage des données en lignes simples (via le code actuel de l'OP ou via la réponse de jotne) inclut le remplacement de l'élément # le délimiteur avec un espace ( )

L'utilisation d'un espace (au lieu d'un # ) comme délimiteur, nous avons le reformatage suivant ldapsearch données (8x champs délimités par des espaces) :

dn: uid=userone,ou=People,dc=team,dc=company,dc=local uid: userone uidNumber: 5000 gidNumber: 5000
dn: uid=usertwo,ou=People,dc=team,dc=company,dc=local uid: usertwo uidNumber: 5001 gidNumber: 5001

En while read peut être modifié pour éliminer les appels de sous-processus (actuellement) 12x (4x $(echo|cut|cut) ) à chaque passage dans le while boucle, par exemple :

while read -r _ dn _ uid _ uidNumber _ gidNumber
do
    echo "############"
    echo ".$dn."
    echo ".$uid."
    echo ".$uidNumber."
    echo ".$gidNumber."
done < <(ldapsearch ... | other_code_to_reformat_ldapsearch_data_as_single_lines_but_with_space_delimiter)

NOTES :

  • le site _ sont des substituts factices pour des champs dont nous ne nous soucions pas.
  • périodes ( . ) ajouté à echo comme délimiteurs visuels

Cela génère :

############
.uid=userone,ou=People,dc=team,dc=company,dc=local.
.userone.
.5000.
.5000.
############
.uid=usertwo,ou=People,dc=team,dc=company,dc=local.
.usertwo.
.5001.
.5001.

Un autre awk idée pour reformater le ldapsearch qui n'affiche que les champs qui nous intéressent :

awk '{for (i=2;i<=NF;i=i+2) {printf (i==2 ? "" : " ") $i}; print ""}' RS= ORS='\n'

Où :

  • on réutilise celui de jotne RS/ORS paramètres
  • (i=2;i<=NF,i=i+2) - n'imprimez que les champs numérotés pairs

Cela génère :

uid=userone,ou=People,dc=team,dc=company,dc=local userone 5000 5000
uid=usertwo,ou=People,dc=team,dc=company,dc=local usertwo 5001 5001

Avec ce changement (4 champs délimités par des espaces au lieu de 8), la proposition de l while read devient :

while read -r dn uid uidNumber gidNumber
do
    ....
done < <(ldapsearch ... | awk '{for (i=2;i<=NF;i=i+2) {printf (i==2 ? "" : " ") $i}; print ""}' RS= ORS='\n')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X