패턴을 검색하고 항상 cn이 포함된 첫 번째 줄을 인쇄합니다.

패턴을 검색하고 항상 cn이 포함된 첫 번째 줄을 인쇄합니다.

다음 출력이 포함된 파일이 있습니다.

dn: rdcPosition이 더 있을 수 있습니다.

acme#6#을 포함하는 rdcPositions가 있는 dn:만 필요합니다.

결과는 cn 및 rdcPosition을 인쇄해야 합니다.

dn: cn=00fa69bd-bede-4918-a017-b59b0901bb3d,ou=Named,ou=Identities,ou=Active,o
 u=Vault,o=acme
rdcPosition: cn=1950,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>8946
 702990</cn><reqdate>1529318977</reqdate><startdate>1529318977</startdate><end
 date>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>1</ne
 wstatus><date>1529318977</date></change><change><date>1529319116</date><previ
 ousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>15
 29481285</date><previousstatus>3</previousstatus><newstatus>6</newstatus></ch
 ange></lifecycle></position>

dn: cn=010903cd-e92d-4307-bffc-4921379153c0,ou=Named,ou=Identities,ou=Active,o
 u=Vault,o=acme
rdcPosition: cn=922445,ou=Entities,ou=Active,ou=Vault,o=acme#5#<position><cn>42
 79084890</cn><reqdate>1429014997</reqdate><startdate>1429014997</startdate><e
 nddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>1</
 newstatus><date>1429014997</date></change><change><date>1429023084</date><pre
 viousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>
 1525107741</date><previousstatus>3</previousstatus><newstatus>6</newstatus></
 change><change><date>1525126716</date><previousstatus>6</previousstatus><news
 tatus>5</newstatus></change></lifecycle></position>
rdcPosition: cn=311982,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>97
 26910833</cn><reqdate>1528120494</reqdate><startdate>1528120494</startdate><e
 nddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>1</
 newstatus><date>1528120494</date></change><change><date>1528123478</date><pre
 viousstatus>1</previousstatus><newstatus>3</newstatus></change></lifecycle></
 position>

dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,o
 u=Vault,o=acme
rdcPosition: cn=914570,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>20
 68839799</cn><reqdate>1406284665</reqdate><startdate>1406284665</startdate><e
 nddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>0</
 newstatus><date>1406284665</date></change><change><date>1406284666</date><pre
 viousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>
 1435847283</date><previousstatus>3</previousstatus><newstatus>6</newstatus></
 change></lifecycle></position>
rdcPosition: cn=999546,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>76
 03071057</cn><reqdate>1400325753</reqdate><startdate>1400325753</startdate><e
 nddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>0</
 newstatus><date>1400325753</date></change><change><date>1400325754</date><pre
 viousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>
 1449224475</date><previousstatus>3</previousstatus><newstatus>6</newstatus></
 change></lifecycle></position>
rdcPosition: cn=3513,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>2802
 042129</cn><reqdate>1406284761</reqdate><startdate>1406284761</startdate><end
 date>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>0</ne
 wstatus><date>1406284761</date></change><change><date>1406284762</date><previ
 ousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>14
 49224599</date><previousstatus>3</previousstatus><newstatus>6</newstatus></ch
 ange></lifecycle></position>
rdcPosition: cn=312936,ou=Entities,ou=Active,ou=Vault,o=acme#3#<position><cn>19
 23461515</cn><reqdate>1449217172</reqdate><startdate>1449217172</startdate><e
 nddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>1</
 newstatus><date>1449217172</date></change><change><date>1449225081</date><pre
 viousstatus>1</previousstatus><newstatus>3</newstatus></change></lifecycle></
 position>

답변1

입력은 다음에 지정된 대로 LDIF로 나타납니다.RFC 2849.

나는 강력히 추천한다아니요LDIF 처리를 위해 일반적으로 사용되는 awk/sed/grep 툴체인을 사용하는 이유는 다음과 같습니다.

  • 긴 속성 값 줄(dn: 포함)은 줄 연속을 나타내기 위해 단일 공백으로 묶입니다.
  • ASCII가 아닌 문자를 포함하는 속성 값은 base64로 인코딩됩니다.

가장 좋은 해결책은 선호하는 스크립팅 언어에 적합한 LDIF 파서를 사용하는 것입니다.

ldif예를 들어 Python의 경우 python-ldap의 모듈을 사용합니다.

문서를 참조하세요:ldif – LDIF 파서 및 생성기

답변2

원하는 출력이 무엇인지 명확하지 않습니다. 이것이 당신에게 얼마나 도움이 될까요?

    awk  '
            {while (match($0, /rdcPosition: [^ ]*acme#6#[^ ]*/))    {print substr ($0, RSTART, RLENGTH)
                                                                     $0  = substr ($0, RSTART + RLENGTH);
                                                                    }
            }
    ' file 
rdcPosition: cn=1950,ou=Entities,ou=Active,ou=Vault,o=acme#6#8946
rdcPosition: cn=311982,ou=Entities,ou=Active,ou=Vault,o=acme#6#97
rdcPosition: cn=914570,ou=Entities,ou=Active,ou=Vault,o=acme#6#20
rdcPosition: cn=999546,ou=Entities,ou=Active,ou=Vault,o=acme#6#76
rdcPosition: cn=3513,ou=Entities,ou=Active,ou=Vault,o=acme#6#2802

댓글 변경 요청이 얼마나 도움이 될까요? 만족스럽지 않다면 원하는 출력을 더 구체적으로 정의하세요.

awk  '
        {DN = $1 FS $2
         while (match($0, /rdcPosition: [^ ]*acme#6#[^ ]*/))    {print DN, substr ($0, RSTART, RLENGTH)
                                                                 $0  =     substr ($0, RSTART + RLENGTH);
                                                                }
        }
' file
dn: cn=00fa69bd-bede-4918-a017-b59b0901bb3d,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=1950,ou=Entities,ou=Active,ou=Vault,o=acme#6#8946
dn: cn=010903cd-e92d-4307-bffc-4921379153c0,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=311982,ou=Entities,ou=Active,ou=Vault,o=acme#6#97
dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=914570,ou=Entities,ou=Active,ou=Vault,o=acme#6#20
dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=999546,ou=Entities,ou=Active,ou=Vault,o=acme#6#76
dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme rdcPosition: cn=3513,ou=Entities,ou=Active,ou=Vault,o=acme#6#2802

답변3

다음 sed스크립트를 사용하십시오(를 사용하여 실행한다고 가정 sed -n).

/^dn:/{                     # this is a "dn" line
    N;                      # append the next line
    s/\n //;                # remove the newline and the space
    x;                      # exchange pattern space with hold space
    /o=acme#6#/p;           # print if pattern space contains our string
    d;                      # delete from pattern space, start next cycle
}
/^rdcPosition:/{            # this is a "rdcPosition" line
    :again;                 # define label for loop
    N;                      # append the next line
    s/\n //;                # remove the newline and the space
    \#</position>#!b again; # if the end tag "</position>" was not read, loop
    /o=acme#6#/H;           # append to hold space if matching what we're looking for
}
${                  # at the very end of input
    x;              # exchange pattern and hold space
    /o=acme#6#/p;   # print if pattern space contains our string
}

sed이 스크립트가 하는 일은 기본적으로 "예약된 공간"(사이클 사이에 예약된 범용 버퍼)에 문자열을 작성하는 것입니다. 문자열은 dn해당 줄에서 시작하여 rdcPosition관심 있는 특정 문자열이 포함된 줄을 추가합니다.

dn줄이 발견되거나 입력이 끝날 때마다 예약된 공간에 문자열이 포함되어 있으면 조건부로 인쇄합니다( rdcPosition현재 dn줄에 일치하는 줄이 없으면 포함되지 않을 수 있습니다).

테스트해보세요:

$ sed -n -f script.sed file
dn: cn=00fa69bd-bede-4918-a017b59b0901bb3d,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme
rdcPosition: cn=1950,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>8946702990</cn><reqdate>1529318977</reqdate><startdate>1529318977</startdate><enddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>1</newstatus><date>1529318977</date></change><change><date>1529319116</date><previousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>1529481285</date><previousstatus>3</previousstatus><newstatus>6</newstatus></change></lifecycle></position>
dn: cn=010903cd-e92d-4307-bffc-4921379153c0,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme
rdcPosition: cn=311982,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>9726910833</cn><reqdate>1528120494</reqdate><startdate>1528120494</startdate><enddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>1</newstatus><date>1528120494</date></change><change><date>1528123478</date><previousstatus>1</previousstatus><newstatus>3</newstatus></change></lifecycle></position>
dn: cn=01126aa4-af80-401b-8713-29e360868999,ou=Named,ou=Identities,ou=Active,ou=Vault,o=acme
rdcPosition: cn=914570,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>2068839799</cn><reqdate>1406284665</reqdate><startdate>1406284665</startdate><enddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>0</newstatus><date>1406284665</date></change><change><date>1406284666</date><previousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>1435847283</date><previousstatus>3</previousstatus><newstatus>6</newstatus></change></lifecycle></position>
rdcPosition: cn=999546,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>7603071057</cn><reqdate>1400325753</reqdate><startdate>1400325753</startdate><enddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>0</newstatus><date>1400325753</date></change><change><date>1400325754</date><previousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>1449224475</date><previousstatus>3</previousstatus><newstatus>6</newstatus></change></lifecycle></position>
rdcPosition: cn=3513,ou=Entities,ou=Active,ou=Vault,o=acme#6#<position><cn>2802042129</cn><reqdate>1406284761</reqdate><startdate>1406284761</startdate><enddate>1924902000</enddate><lifecycle><change><previousstatus/><newstatus>0</newstatus><date>1406284761</date></change><change><date>1406284762</date><previousstatus>1</previousstatus><newstatus>3</newstatus></change><change><date>1449224599</date><previousstatus>3</previousstatus><newstatus>6</newstatus></change></lifecycle></position>

awk위의 코드와 동일한 출력을 생성하는 논리적으로 동등한 스크립트 :sed

/^dn:/  {
    if (hold ~ "o=acme#6#")
        print hold

    hold = $0;
    getline
    hold = hold substr($0, 2)
    next
}

/^rdcPosition:/ {
    line = $0
    while (line !~ "</position>") {
        getline
        line = line substr($0, 2)
    }

    if (line ~ "o=acme#6#")
        hold = hold ORS line
}

END {
    if (hold ~ "o=acme#6#")
        print hold
}

이러한 substr($0, 2)호출은 입력의 구분선에서 선행 공백을 제거합니다.

두 스크립트 모두 해당 dn줄이 정확히 두 줄로 분할되어 있다고 가정합니다.

관련 정보