교대 구분 기호를 사용하여 awk 일치 및 잘라내기 필드

교대 구분 기호를 사용하여 awk 일치 및 잘라내기 필드

샘플 북마크 파일

북마크 파일에 대해 Chrome의 일치 패턴을 사용하거나 유사하게 사용하고 싶고 awk일치 항목을 기반으로 다양한 필드 구분 기호를 기준으로 특정 필드를 잘라냅니다.

샘플 사진을 첨부했습니다. 파일로 추가하는 방법을 찾지 못했습니다.

H3폴더 이름(문자열이 일치하는 경우)과 URL( HREF문자열이 있는 경우) 을 원합니다 .

다음 두 명령은 해당 일치 작업을 완료합니다.

awk -F'[<>]' '/H3/{print $5}' bookmarks.htm
awk -F'"' '/HREF/{print $2}' bookmarks.html

내 목표는 위의 두 명령문을 결합하여 출력이 다음과 같이 되도록 하는 것입니다.

UNIX
url-1
url-2
OCE
url-3
url-4
url-5
ANDROID
url-6
url-7

"if", "then", "else" 를 시도했지만 awk소용이 없었습니다.

어떻게 이를 달성할 수 있나요? 그보다 더 좋은 후보가 있을까요 awk? python, perl은 모두 훌륭하지만 해당 작업을 수행하는 쉘 스크립트를 작성하는 것은 간단한 작업이기 때문에 한 줄짜리는 생각할 필요도 없습니다.

답변1

이것은 HTML 파일을 처리하는 잘못된 방법입니다.sed//... 특수 파서는 거의 없지만 임시 대체용으로 사용됩니다.

sed '
    /\n/{P;d;}
    /<H3/s/[><]/\n/4g
    /HREF/s/"/\n/g
    D
    ' bookmarks.htm

GNU가 아닌 버전의 경우sed:

sed '
    /\n/{P;d;}     #if there is more then 1 line «P»rint 1st line then «d»elete all
    /<\/H3/s//\n/  #replace «</H3» by «\n»ewline
    /\n/s/">/\n/   #replace «">» by «\n»ewline if previous command is executed
    /HREF/s/"/\n/g #put «\n»ewline» around url if «HREF» in line
    D              #«D»elete 1 first line, go to start
    ' bookmarks.htm

답변2

xml/html 파서/프로세서를 사용하면 몇 가지 장점이 있습니다.X 경로표현식은 특정 부품을 선택하는 표준 방법입니다.

xml + xmlstarlet + xpath

입력이 올바른 형식의 xml이면 xmlstarlet + xpath 표현식을 사용할 수 있습니다.

xmlstarlet sel -t -v '//h3|//a/@href' -nl bookmarks.html

html+xmllint:xml

입력이 유효한 HTML인 경우 이를 xml로 변환할 수 있습니다(다음을 사용).xmllint) 이전을 사용하십시오.

xmllint -html -xmlout ex.html | xmlstarlet sel -t -v '//h3|//a/@href' -nl -

xmllint + xpath

xmllint + xpath 표현식을 직접 사용할 수 있습니다

xmllint -html -xpath '//h3/text()|//a/@href' bookmarks.html

...하지만 출력 형식이 다릅니다...

답변3

마지막 대답: 이번에는 사자 펄입니다

perl -nE 'say $1 if (/<h3.*?>(.*?)<\/h3>/i or /href="(.*?)"/i)' ex.html

(저는 XML 파서 기반 솔루션이 더 좋다고 생각합니다. 하지만 도구 생성 파일이 있기 때문에 놀랄 일이 많아지면 안 됩니다.)

답변4

이제 나는 퀴프의 필요성을 포기하고 그냥 대본으로 했습니다.

댓글이 너무 길어져서 이렇게 답변을 드렸습니다. 하지만, 자유롭게 응답해주시기 바랍니다.

이 스크립트는 작업을 수행하지만 너무 느립니다. 속도를 높이거나 농담을 제안할 수 있는 사람이 있습니까?

#!/bin/sh
file=$1
while IFS= read -r line
do
hdr=$(echo $line | awk -F'[<>]' '/H3/{print $5}')
url=$(echo $line | awk -F'"' '/HREF/{print $2}')
if [ ${url} ]; then
    echo $url
elif [ ${hdr} ]; then
    echo $hdr
fi
done <"$file"

파일은 다음과 같습니다. (드디어 얻었습니다)

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
  <h1>Bookmarks</h1>
  <dl>
    <dd>
        <DT><H3 ADD_DATE="1484311924" LAST_MODIFIED="1485532328">UNIX</H3>
      <dl>
        <dt><a HREF="http://unix.stackexchange.com/questions/223182/how-to-replace-spaces-in-all-file-names-with-underscore-in-linux-using-shell-scr" add_date="1484311897">url-1</a></dt>
        <dt><a HREF="http://unix.stackexchange.com/questions/81349/how-do-i-use-find-when-the-filename-contains-spaces"        add_date="1484738308">url-2</a></dt>
      </dl>
    </dd>
    <dd>
        <DT><H3 ADD_DATE="1486550854" LAST_MODIFIED="1487228526">OCE</H3>
      <dl>
        <dt><a HREF="http://www.oraclecertificationprep.com/apex/f?p=OCPSG%3AEXAM_DETAILS%3A%3A%3ANO%3A%3AP2_EXAM%3A1Z0-061"    add_date="1486550866">url-3</a></dt>
        <dt><a HREF="http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=303&amp;p_certName=SQ1Z0_047" add_date="1486550898">url-4</a></dt>
        <dt><a HREF="https://www.quora.com/How-do-you-prepare-for-an-Oracle-Database-SQL-exam" add_date="1486550950">url-5</a></dt>
      </dl>
    </dd>
    <dd>
        <DT><H3 ADD_DATE="1487084050" LAST_MODIFIED="1487228595">ANDROID</H3>
      <dl>
        <dt><a HREF="https://material.io/guidelines/style/color.html#" add_date="1487228526">url-6</a></dt>
        <dt><a HREF="https://developer.android.com/index.html" add_date="1487228539">url-7</a></dt>
      </dl>
    </dd>
  </dl>
</body>
</html>  

관련 정보