同じ行にある2つの検索パターン間の値を抽出します。

同じ行にある2つの検索パターン間の値を抽出します。

Output.dat ファイルには次の内容があります。dn: uid=との間の値を抽出する必要があります。,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
  • 使ってみよう
    sed -e '/dn: uid=/,/,ou=/p' output.dat but
    
    値の代わりに行全体を返します。
  • 使用しようとすると
    sed -e '/dn: uid=/,/,ou=/\1/p' output.dat
    
    その後、次のエラーが発生します。
    sed: -e expression #1, char 18: unknown command: `\'
    

答え1

PCRE()をサポートするGNU grepバージョンがある場合は、-P次のことを意味するとします。最初起こった,ou

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

似合いたい場合第二 ,ounon-greedy?修飾子を削除できます。

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

括弧内の式は長さ0のアサーション(別名周りを見てください) は一致の一部を構成しますが、結果の一部として返されないことを意味します。 Perlでも基本的に同じことができます。

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

何かできます。似たようなsedでは、一般(ゼロ以外の長さ)のグループ化を使用します。たとえば、GNU sedの場合、他のバリアントでは追加のエスケープが必要になることがあります。

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

または少し単純化

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

sedには貪欲ではない一致オプションがないので、[^,]これは少しハッキングです。


後で考える:これは正確に要求された操作を実行しませんが、実際に必要な操作はname=valueファイルからコンマで区切られたペアを読み取り、最初のフィールドの値を名前からさらに分離するようです。以下を含むさまざまな方法でこれを達成できます。

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

または、次の純粋なbashソリューション

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

答え2

これはawkにとって良いことです。正規表現を使用する代わりに文字列を分割できます。解決策は次のとおりです。

$ awk -F= '{ split($2,arr,","); print arr[1]  }' test.txt
user1
[email protected]
usertest
abc1

答え3

そしてsed

sed 's/[^=]*=\([^,]\+\),.*/\1/' file

これはuid=、その行に最初の発生があると仮定し、その行の最初のインスタンスで停止=したいとします。,ou=

説明する

=これにより、文字以外の文字([^=]*)の後に=一致する文字を好きなだけ探し、カンマ以外の文字(\([^,]\+\))の後にカンマと行の残りの部分(,.*)をできるだけ保存します。つまり、最初のコンマの前と後のすべての内容を、その行の=最初のコンマの後にある非カンマ文字で置き換えます。=

答え4

長さ順にいくつかの追加オプション:

  1. grepPCREを使用したGNU

    grep -oP 'uid=\K[^,]+' file 
    

    \Kスイッチと組み合わせると、印刷された後、-o最もgrep長い文字ではなく結果のみが生成されます。,uid=

  2. awk

    awk -F'[=,]' '{print $2}' file 
    

    -F'[=,]フィールド区切り文字を次に設定するか、=2番目の,フィールドはユーザー名です。

  3. sed

    sed -r 's/.{8}([^,]*).*/\1/' file 
    

    これは最初の7文字(.{7})と一致し、=最も長い,非部分をキャプチャし、\1行全体をに置き換えます\1

  4. perl

    perl -pe 's/.+?=([^,]+).*/$1/' file 
    

    -pe「-eで指定されたスクリプトを適用した後に各行を印刷します」を意味します。は代替演算子でありs///、正規表現は最初の(.+??可能な限り短い文字列と一致するように)検索し、次に最長の=非文字セグメントをキャプチャします。キャプチャされたコンテンツ(括弧内のコンテンツ)と一致するコンテンツを,置き換えます。s///

  5. cut

    cut -d'=' -f 2 file | cut -d ',' -f 1 
    

    -d区切り記号をに設定する=と、2番目の(-f 2)フィールドはになりますusername,ou。 2番目は区切り文字cutとして機能し、ユーザー名を別々に印刷します。,

関連情報