패턴을 검색하여 같은 줄에 인쇄

패턴을 검색하여 같은 줄에 인쇄

다음 형식의 큰 .txt 파일이 있습니다.

  Pin name="AR_OP" status="f" 
      Pref x=997.6800 y=2327.0400 side=N width=0.0400 depth=0.3750 /
      Layer id=1 
--
  Pin name="AW_OP" status="f" 
      Pref x=997.6800 y=2327.0400 side=S width=0.0400 depth=0.3750 /
      Layer id=2 

내가 원하는 출력은 다음과 같습니다.

Pin name="AR_OP" side=N
Pin name="AW_OP" side=S

검색하고 싶은 부분마다핀 이름내가 원하는 핀 이름과 일치합니다.같은 줄에. 누구든지 도울 수 있습니까?

답변1

모든 공백을 개행 문자로 바꾸고 , Pin또는 로 시작하는 name=줄을 빼냅니다 side=. 이렇게 하면 세 그룹으로 구성된 라인이 제공됩니다. 세 줄로 구성된 각 세트를 공백을 구분 기호로 사용하여 한 줄로 다시 포맷합니다.

$ tr ' ' '\n' <file | grep -e '^Pin$' -e '^name=' -e '^side=' | paste -d ' ' - - -
Pin name="AR_OP" side=N
Pin name="AW_OP" side=S

이는 모든 값에 공백이 포함되어 있지 않다고 가정합니다.


문서가 다음과 같은 XML 문서로 시작되었다고 가정합니다.

<?xml version="1.0"?>
<root>
  <Pin name="AR_OP" status="f">
    <Pref x="997.6800" y="2327.0400" side="N" width="0.0400" depth="0.3750"/>
    <Layer id="1"/>
  </Pin>
  <Pin name="AW_OP" status="f">
    <Pref x="997.6800" y="2327.0400" side="S" width="0.0400" depth="0.3750"/>
    <Layer id="2"/>
  </Pin>
</root>

그러면 데이터는 다음에서 더 잘 얻을 수 있습니다.이것후처리 변형에는 텍스트 처리 도구 대신 XML 인식 도구를 사용하십시오.

예를 들어,

xmlstarlet select --template \
    --match  '//Pin' --output 'Pin' \
    --output ' name="' --value-of '@name'      --output '"' \
    --output ' side="' --value-of 'Pref/@side' --output '"' \
    -nl file

이는 입력 문서에서 모든 노드를 xmlstarlet찾는 데 사용됩니다 . Pin그런 다음 이를 반복하여 해당 name속성과 Pref하위 노드의 속성을 요청된 형식으로 출력합니다.side

유사한 방법그리고xq, 잘 알려진 JSON 파서 주변의 jqXML 파서 래퍼 :

xq -r '.root.Pin | map("Pin name=\"\(."@name")\" side=\"\(.Pref."@side")\"")[]' file

답변2

가정된 값에는 side항상 하나 이상의 대문자가 포함됩니다.

awk '{
    if (match($0, /Pin name="[^"]+"/)) {
        printf "%s ", substr($0, RSTART, RLENGTH)
        next
    }
    if (match($0, /side=[A-Z]+/)) {
        printf "%s\n", substr($0, RSTART, RLENGTH)
    }
}' file

이는 일치하는 부분과 공백 또는 개행 문자만 출력합니다.

답변3

펄 사용:

$ perl -lne 'if (/^\s*(Pin name="[^"]*").*/) {
               $pin = $1;
               $_ = <>;
               if (/(side=.)/) {
                 $side = $1;
                 printf "%s %s\n", $pin, $side;
               }
             }' input.txt
Pin name="AR_OP" side=N
Pin name="AW_OP" side=S

영어로:

현재 줄이 일치하면 Pin name"[^"]*"캡처 그룹( $1)을 사용하여 이를 추출하고 변수에 저장한 $pin후 다음 줄( $_ = <>;)을 읽습니다. "side=."가 포함되어 있으면 변수로 추출 $side하고 사이에 공백을 두고 $pin과 $side를 인쇄합니다. 다른 모든 입력 라인은 무시됩니다.

또 다른 변형은 다음과 같습니다.

$ perl -lne 'if (/^\s*(Pin name="[^"]*").*/) {
               $pin=$1;
               ($side = <>) =~ s/^.*(side=.).*/\1/;
               printf "%s %s", $pin, $side if $side =~ /side=/
             }' input.txt 
Pin name="AR_OP" side=N
Pin name="AW_OP" side=S

영어로:

현재 줄이 "핀 이름..."과 일치하면 추출되어 $pin 변수에 저장됩니다. 그런 다음 다음 줄을 ($side = <>)변수로 읽어 들여 $side$side를 수정하여 "side="를 제외한 모든 항목을 제거합니다. ( =~ s/^.*(side=.).*/\1/;) 그런 다음 둘 다 인쇄하십시오.만약에 $side포함하다 /side=/.


그건 그렇고, 그 ($side = <>) =~ s/^.*(side=.).*/\1/;줄은 변수를 할당한 다음 바꾸기 작업을 사용하여 즉시 수정하는 데 유용한 perl 관용구의 예입니다( s///. tr///도 작동합니다). 이는 $side=<>다음 줄을 $side로 읽은 다음 $side =~ s/^.*(side=.).*/\1/;$side를 수정하는 두 가지 명령문과 동일합니다 .

할당 주위의 괄호는 중요합니다. 그렇지 않으면 변수에 성공/실패 또는 대체 작업 수가 포함됩니다(그러나 할당의 오른쪽이 =수정 가능한 변수인 경우에만 해당). 그렇지 않은 경우 파일 핸들과 같이 수정 불가능한 변수인 경우 , 그러면 그것은 단지 문법적 오류입니다).

답변4

사용그리고:

텍스트 파일(있는 그대로) 그리고또는:

xidel -e '//Pin/concat(
    "Pin Name=&quot;", @name, "&quot; side=&quot;", ./Pref/@side, "&quot;"
)' file.html

산출

Pin Name="AR_OP" side="N"
Pin Name="AW_OP" side="S"

관련 정보