GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wert zwischen zwei Suchmustern in derselben Zeile extrahieren?

Ich habe folgendes in einer Datei Output.dat. Ich muss den Wert zwischen dn: uid= extrahieren und ,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
  • Ich habe versucht,
    sed -e '/dn: uid=/,/,ou=/p' output.dat but
    

    Es gibt eine vollständige Zeile anstelle des Werts zurück.

  • Bei Versuch,
    sed -e '/dn: uid=/,/,ou=/1/p' output.dat
    

    bekam dann folgenden Fehler:

    sed: -e expression #1, char 18: unknown command: `'
    

Akzeptierte Antwort:

Wenn Sie eine Version von GNU grep mit PCRE (-P ) unterstützen, dann vorausgesetzt, Sie meinen den ersten Vorkommen von ,ou

grep -oP '(?<=dn: uid=).+?(?=,ou=)' file

Wenn Sie auf die Sekunde passen möchten ,ou Sie können das nicht gierige ? entfernen Modifikator

grep -oP '(?<=dn: uid=).+(?=,ou=)' file

Die Ausdrücke in Klammern sind Zusicherungen der Länge Null (auch bekannt als lookarounds ), was bedeutet, dass sie Teil des Spiels sind, aber nicht als Teil des Ergebnisses zurückgegeben werden. Sie könnten dasselbe nativ in Perl machen, z. B.

perl -ne 'print "$1n" if /(?<=dn: uid=)(.+?)(?=,ou=)/' file 

Es ist möglich, etwas ähnliches zu tun in sed unter Verwendung einer regulären Gruppierung (ohne Länge null), z. (für GNU sed – andere Varianten müssen eventuell zusätzlich maskiert werden)

sed -rn 's/(.*dn: uid=)([^,]+)(,ou=.*)/2/p' file

oder etwas vereinfachen

sed -rn 's/.*dn: uid=([^,]+),ou=.*/1/p' file

Beachten Sie den [^,] ist hier ein bisschen ein Hack, da sed keine echte nicht-gierige Übereinstimmungsoption hat.

Nachtrag :Obwohl es nicht genau das ist, was Sie gefragt haben, sieht es so aus, als ob Sie eigentlich den durch Kommas getrennten name=value lesen möchten Paare aus einer Datei, und trennen Sie dann den Wert des ersten Felds weiter von seinem Namen. Sie können dies auf viele Arten erreichen – einschließlich

awk -F, '{sub(".*=","",$1); print $1}' file

oder eine reine Bash-Lösung wie

while IFS=, read -r a b c d; do printf '%sn' "${a#*=}"; done < file 

Linux
  1. Linien zwischen (und ausschließenden) zwei Mustern drucken?

  2. Zeilen zwischen (und einschließlich) zwei Mustern drucken?

  3. Wie fügt man Text vor der ersten Zeile einer Datei ein?

  4. Text zwischen zwei bestimmten Zeilen extrahieren?

  5. Bash-Skript fügt Text an die erste Zeile einer Datei an

So entfernen Sie Zeilen aus einer Datei mit dem Sed-Befehl

Verwenden von Sed zum Suchen und Ersetzen einer Linie zwischen Musterbereichen

So extrahieren Sie die Tar.xz-Datei in der Linux-Befehlszeile

Unix Sed Tutorial:Drucken von Dateizeilen mit Adresse und Mustern

Unterschied in Leerzeichen zwischen zwei Dateien unter Linux

Verwenden von sed zum Ersetzen zwischen einem bestimmten Muster