awk 명령은 일치하는 패턴에서 다음 줄을 가져오고 두 패턴 사이의 문자열을 자릅니다.

awk 명령은 일치하는 패턴에서 다음 줄을 가져오고 두 패턴 사이의 문자열을 자릅니다.

일치하는 패턴 다음에 다음 행을 가져와야 하고 해당 행에서 두 패턴 사이의 값을 자르거나 잘라야 합니다.

샘플 소스 파일

<h2>Commodity Information</h2>

<dl>
        <dt>Commodity Orgin</dt>
        <dd>uerb45e001.material.com</dd>

        <dt>Commodity Code & Dimension</dt>
        <dd>151151.15 Dim 90 </dd>

        <dt>Commodity Serial #</dt>
        <dd>2009081020</dd>

        <dt>Client Name</dt>
        <dd>Jack</dd>

</dl>

원하는 출력:

Commodity Orgin : uerb45e001.material.com
Commodity Code & Dimension : 151151.15 Dim 90
Commodity Serial # : 2009081020
Client Name : Jack

답변1

lynx -dumpHTML을 일반 텍스트로 변환한 다음 awk필드 구분 기호를 줄 바꿈 문자( \n)로 설정하고 레코드 구분 기호를 두 개 이상의 줄 바꿈 문자( \n\n+)로 설정하여 출력 형식을 다시 지정합니다.

sub()스크립트의 함수 호출은 awk원하는 출력을 인쇄하기 전에 불필요한 공백을 제거합니다.

$ lynx -dump ramp.html | 
    awk -v RS='\n\n' -F'\n' '/^[[:space:]]+/ {
        sub(/^ +/,"",$1);
        sub(/ +/," ",$2);
        print $1":"$2
    }'
Commodity Orgin: uerb45e001.material.com
Commodity Code & Dimension: 151151.15 Dim 90
Commodity Serial #: 2009081020
Client Name: Jack

XML이나 HTML을 구문 분석하는 것은 결코 좋은 생각이 아니기 때문에 나는 이 작업을 정말 좋아하지 않습니다.정규 표현식 사용. 그것작동하지 않습니다. 작동하는 것처럼 보이도록 해킹할 수 있다고 해도 매우 취약하고~ 할 것이다HTML이나 XML이 정규식이 찾고 있는 것에서 충분히 변경되면 중단됩니다. 실제 XML 또는 HTML 파서는 다음과 같습니다.오직작업을 올바르게 수행하는 것.

그러나 다음은 UNIX 계열 시스템에서 사용할 수 있는 sed몇 가지 도구입니다.fmt

$ sed -e '/<d[td]\|^[[:blank:]]*$/!d
          s/<[^>]*>//g;
          s/^ *//;
          /^\(Commodity\|Client\)/ s/$/:/' ramp.html | 
      fmt |
      sed -e '/^[[:blank:]]*$/d'
Commodity Orgin: uerb45e001.material.com
Commodity Code & Dimension: 151151.15 Dim 90
Commodity Serial #: 2009081020
Client Name: Jack

첫 번째 sed스크립트는 모든 줄을 삭제합니다.와는 별개로<DT>또는 태그가 포함된 빈 줄과 줄이 <DD>있으면 입력에서 모든 HTML 태그가 제거되고 선행 공백이 제거되며 :필드 이름 줄 끝에 가 추가됩니다. 그런 다음 출력을 sed파이프로 연결하여 fmt줄 형식을 다시 지정하고 sed다시 빈 줄을 제거합니다.

이는 해킹이며 귀하가 제공한 샘플 입력을 정확하게 처리하는 것만 보장됩니다. 큰 차이가 있으면 스크립트가 손상될 수 있습니다. 이는 정규식을 사용하여 가장 단순한 HTML이나 XML을 제외한 모든 항목을 구문 분석할 때 발생하는 현상입니다.

답변2

가 있고 xmlstarlet입력이 유효한 XML(병합)인 경우 다음과 같이 할 수 있습니다.

xmlstarlet sel --text -t -m //dt -v 'concat(., " : ", following::dd)' -nl input.html

답변3

paste -d: <(grep -oP '<dt>\K.*(?=<)' file.html) <(grep -oP '<dd>\K.*(?=<)' file.html) | sed 's/:/ : /'

Commodity Orgin : uerb45e001.material.com
Commodity Code & Dimension : 151151.15 Dim 90 
Commodity Serial # : 2009081020
Client Name : Jack
  • 와 태그 사이의 텍스트를 grep추출하는 두 가지 명령 (OP의 예제 파일에 제공된 것과 동일한 줄에 있다고 가정)<dt><dd>
  • paste두 파일을 한 줄씩 결합하여 :구분 기호로 사용
  • sed이 명령은 OP의 예상 출력에 따라 ":" 구분 기호를 ":"으로 바꿉니다(태그 사이의 텍스트에 : 문자도 포함되어 있으면 이 해킹은 작동하지 않습니다).
  • 이것 좀 봐답변사용에 대한 설명 \K(?=)

관련 정보