J'ai ce qui suit dans un fichier Output.dat. J'ai besoin d'extraire la valeur entre dn: uid=
et ,ou=
dn: uid=user1,ou=Active,ou=Member,dc=domain,dc=org
dn: [email protected],ou=Active,ou=Member,dc=domain,dc=org
dn: uid=usertest,ou=Active,ou=Member,dc=domain,dc=org
dn: uid=abc1,ou=Active,ou=Member,dc=domain,dc=org
- J'ai essayé d'utiliser
sed -e '/dn: uid=/,/,ou=/p' output.dat but
il renvoie la ligne complète au lieu de la valeur.
- Lorsque vous essayez d'utiliser
sed -e '/dn: uid=/,/,ou=/1/p' output.dat
puis j'ai eu l'erreur suivante :
sed: -e expression #1, char 18: unknown command: `'
Réponse acceptée :
Si vous avez une version de GNU grep avec PCRE (-P
) support, alors en supposant que vous vouliez dire le premier occurrence de ,ou
grep -oP '(?<=dn: uid=).+?(?=,ou=)' file
Si vous voulez correspondre à la seconde ,ou
vous pouvez supprimer le ?
non gourmand modificateur
grep -oP '(?<=dn: uid=).+(?=,ou=)' file
Les expressions entre parenthèses sont des assertions de longueur nulle (alias lookarounds ) ce qui signifie qu'ils font partie du match, mais ne sont pas renvoyés dans le cadre du résultat. Vous pouvez faire la même chose nativement en perl, par exemple
perl -ne 'print "$1n" if /(?<=dn: uid=)(.+?)(?=,ou=)/' file
Il est possible de faire quelque chose de similaire dans sed, en utilisant un groupement régulier (non de longueur nulle), par ex. (pour GNU sed - d'autres variétés peuvent nécessiter un échappement supplémentaire)
sed -rn 's/(.*dn: uid=)([^,]+)(,ou=.*)/2/p' file
ou en simplifiant légèrement
sed -rn 's/.*dn: uid=([^,]+),ou=.*/1/p' file
Notez le [^,]
est un peu un hack ici, car sed n'a pas de véritable option de correspondance non gourmande.
Réflexion après coup :bien que ce ne soit pas exactement ce que vous avez demandé, il semble que ce que vous voulez réellement faire est de lire name=value
séparé par des virgules paires d'un fichier, puis séparez davantage la valeur du premier champ de son nom. Vous pouvez y parvenir de plusieurs façons, y compris
awk -F, '{sub(".*=","",$1); print $1}' file
ou une solution purement bash telle que
while IFS=, read -r a b c d; do printf '%sn' "${a#*=}"; done < file