bash, grep 또는 sed를 사용하여 파일에서 첫 번째 정규식 결과를 얻으려면 어떻게 해야 합니까?

bash, grep 또는 sed를 사용하여 파일에서 첫 번째 정규식 결과를 얻으려면 어떻게 해야 합니까?

이라는 파일이 있는데 다음과 같은 결과를 얻었 index.html습니다 grep '<td class="headerCovTableEntryLo">' index.html.

<td class="headerCovTableEntryLo">39.2 %</td>
<td class="headerCovTableEntryLo">56.6 %</td>

39.2만 구하면 됩니다. 어떻게 해야 하나요?

답변1

XML 파서를 사용할 수 있습니다(예 xmlstarlet: .

xmlstarlet fo -H page.html |
    xmlstarlet sel -t -v '//td[@class="headerCovTableEntryLo"][1]' -n 2>/dev/null |
    tr -dc '[:digit:].\n'

산출

39.2

첫 번째 호출에서는 xmlstarletHTML을 구문 분석하고 가능한 경우 이를 XML로 변환합니다. 두 번째 호출은 XML을 구문 분석하고 <td/>일치하는 속성이 있는 첫 번째 요소 값을 추출합니다. 마지막 것은 문자열에서 공백과 퍼센트 문자를 제거합니다(실제로 숫자, 점, 개행 문자를 제외한 모든 것을 제거합니다).classheaderCovTableEntryLotr

더 정확한 일치가 필요한 경우 경로를 //...더 구체적으로 만들거나 더 많은 HTML을 게시해야 합니다.

호출을 피하려면 tr첫 번째 공백을 제외한 요소 값을 반환하면 됩니다(따라서 39.2 %로 반환됩니다 39.2).

xmlstarlet fo -H page.html |
    xmlstarlet sel -t -v 'substring-before(//td[@class="headerCovTableEntryLo"][1], " ")' -n 2>/dev/null

답변2

GNU가 있는 경우 grep-P옵션을 사용하여 Perl 호환 정규 표현식을 활성화할 수 있습니다. 이는 \K"지금까지 일치하는 항목을 모두 무시"를 의미하는 regex 명령을 제공합니다. -m1첫 번째 일치에서 중지하고 -o해당 줄의 일치하는 부분만 인쇄하는 것과 결합하여 다음을 수행할 수 있습니다.

$ grep -m1 -oP '<td class="headerCovTableEntryLo">\K[0-9.]' file
39.2

또는 유사하게:

$ grep -m1 -oP '(?<=<td class="headerCovTableEntryLo">)[0-9.]+' file
39.2

또는 다음을 사용하십시오 awk.

$ awk -F'[> ]' '/<td class="headerCovTableEntryLo">/{print $3; exit}' file
39.2

답변3

GNU를 사용하면 첫 번째 일치 후에 종료를 사용할 grep수 있습니다 . -m 1예를 들어

grep -m 1 '<td class="headerCovTableEntryLo">' index.html 

에서 man grep:

-m NUM, --max 개수=NUM

NUM줄을 일치시킨 후 파일 읽기를 중지합니다. 입력이 일반 파일의 표준 입력이고 NUM 출력이 줄과 일치하는 경우 grep은 후행 컨텍스트 줄이 있는지 여부에 관계없이 종료하기 전에 마지막 일치 줄 뒤에 표준 입력이 위치하도록 합니다. 이를 통해 호출 프로세스가 검색을 재개할 수 있습니다.

NUM개의 일치하는 줄 이후에 grep이 중지되면 모든 후행 컨텍스트 줄을 인쇄합니다.

-c or--count option is also used, grep does not output a count greater than NUM. When the-v --invert-match` 옵션 과 함께 사용하면 일치하지 않는 NUM개 행을 출력한 후 grep이 중지됩니다.or

그런 다음 해당 값만 추출하려면 sed로 파이프하세요. 예를 들어

$ grep -m 1 '<td class="headerCovTableEntryLo">' index.html |
    sed -e 's/^[^>]*>//; s/ %.*//'
39.2

아니면 잊어버리고 grep모든 일을 끝내세요 sed.

$ sed -ne '/<td class="headerCovTableEntryLo">/ {s/^[^>]*>//; s/ %.*//p;q}' index.html 
39.2

그러나 실제로는 HTML 파서를 사용해야 합니다. HTML, XML, JSON 등과 같은 구조화된 데이터에만 정규식을 사용하면 실패할 수 있습니다.

답변4

모든 도구 grep, awk 및 sed를 완료하려면 다음을 수행하세요.

sed -En '/<td class="headerCovTableEntryLo">([0-9.]+).*/{s//\1/p;q}'

관련 정보