파일에서 텍스트를 찾아 csv로 복사

파일에서 텍스트를 찾아 csv로 복사

여러 HTML 파일(약 500K)에서 텍스트를 추출해야 합니다. 복사할 텍스트는 다음과 같습니다.<div class='cls '>text to be copied including some<span>and <p></p></span>and more text</div>

내가 결정한다(?:\<div\sclass\=\'cls\s\'\>)(.*)(?=\<\/div\>)

grep을 사용하여 이 작업을 수행하는 방법에 대한 다른 질문을 읽었으며 명령은 다음과 같습니다.

grep -r "/(?:\<div\sclass\=\'cls\s\'\>)(.*)(?=\<\/div\>)/" *.html > output.txt

그러나 이것은 작동하지 않습니다. 내가 뭘 잘못했나요?

또한 시도했습니다 pcregrep -r -regexp="/(?:\<div\sclass\=\'cls\s\'\>)(.*)(?=\<\/div\>)/" --file-list=fl.txt > output.txt– 아무것도 하지 않았습니다 pcregrep -r -regexp="/(?:\<div\sclass\=\'cls\s\'\>)(.*)(?=\<\/div\>)/" > output.txt– 아무것도 하지 않았습니다

편집 1: 다음 형식 제안을 시도해 보십시오.

grep -f -r "/(?:\<div\sclass\=\'desc\s\'\>)(.*)(?=\<\/div\>)/" *.html >> touch output.txt
grep: -r: No such file or directory
grep -f -r "/(?:\<div\sclass\=\'desc\s\'\>)(.*)(?=\<\/div\>)/" *.html >> output.txt
grep: -r: No such file or directory
grep -f -r "/(?:\<div\sclass\=\'desc\s\'\>)(.*)(?=\<\/div\>)/" *.html >> output.txt
grep: -r: No such file or directory

 grep -f "/(?:\<div\sclass\=\'desc\s\'\>)(.*)(?=\<\/div\>)/" file111.html >> touch output.txt
grep: /(?:\<div\sclass\=\'desc\s\'\>)(.*)(?=\<\/div\>)/: No such file or directory

그리고 다른 순열은 아직 없습니다

답변1

왜 이렇게 멋진 광고 종소리와 휘파람을 추가했는지 잘 모르겠습니다. 이 간단한 정규식은 나에게 효과적입니다.

grep "<div\sclass='cls\s'>.*<\/div>" file
<div class='cls '>text to be copied including some<span>and <p></p></span>and more text</div>

답변2

다음과 같은 6가지 질문이 있습니다.

  1. /정규식의 시작과 끝 부분에 콘텐츠를 포함합니다 . 검색할 다른 프로그램을 입력하지만 필요하지 않습니다. 실제로 패턴에는 리터럴 문자만 포함됩니다./regex/sedvigrepgrep/
  2. (일반)에서 PCRE를 사용하려면 grep를 사용해야 합니다 -P.
  3. 그런 일은 없을 -regexp것입니다 --regexp. 또는 에서와 같이 이를 생략하고 —regexp=정규식을 순진한 인수로 제공합니다 grep.

위의 오류를 수정한 후에는 ( grep -P및 ) 명령이 모두 작동했지만 앞이나 뒤의 텍스트를 pcregrep포함하여 패턴이 포함된 전체 줄을 인쇄했습니다 .<div …></div>

  1. 패턴과 일치하는 텍스트만 인쇄하려면 를 지정해야 합니다 -o.

문제를 해결했지만 여전히 <div …>출력에 해당 내용이 표시됩니다(그러나 이전 텍스트 <div …></div>이후의 텍스트는 표시되지 않음). 그래서,

  1. 후방 보기 그룹에 문제가 있습니다. 경쟁에 포함되어 있습니다.

    안타깝게도 저는 문제가 무엇인지, 해결 방법을 정확히 알 수 있을 만큼 PCRE에 대해 충분히 알지 못합니다. 다행히도 나는 pcregrep해결책을 충분히 알고 있습니다. 정규식에 캡처링 그룹이 여러 개 있는 경우 pcregrep출력을 쓸 캡처링 그룹을 선택할 수 있습니다. 따라서 pcregrep LookBehind를 캡처 그룹으로 변환한 다음 이를 무시하여 작동하게 할 수 있습니다.

    pcregrep -o2-r "(\<div\sclass\=\'cls\s\'\>)(.*)(?=\<\/div\>)"

    그러나 이것조차도 필요한 것보다 더 복잡합니다. 첫 번째( <div …>) 그룹은 캡처 그룹일 필요는 없습니다. 즉, 그룹일 필요는 없습니다. 마찬가지로 마지막 그룹( </div>예측 그룹)은 그룹일 필요가 전혀 없습니다. 그룹이 되어야 하는 유일한 것은 캡처하려는 부분 <div …>과 다음 사이의 부분 입니다 </div>.

    pcregrep-o1-r "\<div\sclass\=\'cls\s\'\>(.*)\<\/div\>"

    이제 세트가 하나만 있기 때문에  -o2으로 변경했습니다 .-o1

    그런데 다음과 같이루딕이 발견했습니다(그러나 언급되지는 않음) 이러한 백슬래시는 거의 필요하지 않습니다. AFAICT, 필요한 것은 \s문자열에 있는 것뿐이므로 위의 내용을 다음과 같이 단순화할 수 있습니다.

    pcregrep -o1 -r "<div\sclass='cls\s'>(.*)</div>"

    이제 정규식의 모든 PCRE 부분(앞으로 및 뒤로)을 제거했으므로 이 정규식을 일반 정규식과 비교할 수 있다고 생각할 수 있습니다 grep. 불행하게도 위 명령은 옵션에 따라 다릅니다. 아니요.-oNgrep

    그러나 !와 결합할 수 있습니다 sed.

    sed -n -r "s|.*<div\sclass='cls\s'>(.*)</div>.*|\1|p"

    해당 pcregrep명령과 마찬가지로 이 명령은 전체 정규식( 처음과 끝에 항목을 추가 했기 때문에 <div …>이전 또는 이후에 오는 항목 포함 )을 검색하고 이를 #1 캡처 그룹(유일한 항목)으로 바꿉니다. 마지막 옵션은 일치하는 행을 인쇄하게 하며, 이 옵션은 일치하지 않는 행을 인쇄하지 않도록 합니다.</div>.*p-n

    위의 |정규식에는 가 포함되어 있으므로 정규식 구분 기호로 작동합니다 /. 이를 구분 기호로 사용하려면 /텍스트를 이스케이프해야 합니다 /( </div>).

    sed -n -r "s/.*<div\sclass='cls\s'>(.*)<\/파티션>.*/\1/"

    불행히도 sed재귀 검색 기능은 없습니다. 이 옵션은 -rERE(확장 정규 표현식) 사용을 지정하는 것과 유사합니다 . 이것이 없으면 및 캡처 그룹을 사용해야 합니다.sed-Egrep\(\)

    sed -n "s/.*<div\sclass='cls\s'>\(.*\)<\/div>.*/\1/p"

    sed물론 를 실행하여 재귀 검색을 수행할 수 있습니다 find.

    PS 한 줄에 ... 쌍이 여러 개인 경우 <div …>이 명령은 첫 번째 쌍만 인쇄합니다.</div>sed

  2. 재귀(디렉토리 트리) 검색이 잘못되었습니다.

    grep -r정규식*.html

    ( pcregrep다시) 각 파일을 살펴 .html보고모든어떤 파일이든 이름이 다음으로 끝나는 디렉토리 .html. 따라서 (아마도?) 라는 하위 디렉터리가 있는 경우 foo.html위 명령은 검색을 수행합니다.모든Makefile해당 디렉토리에 있는 파일입니다( 또는 라고 불리는 경우에도 마찬가지입니다 README.txt). (내 생각에는) page42및 와 유사한 이름을 가진 하위 디렉터리가 있는 경우 index해당 디렉터리는 검색되지 않습니다.

    당신이하고 싶은 일은 :

    grep -r --include='*.html'정규식.

    다음에서 시작하는 모든 디렉토리에 대해 재귀 검색을 수행합니다..(현재 디렉터리) 이름이 일치하는 파일만 봅니다 *.html.

답변3

grep -r "/(?:\<div\sclass\=\'cls\s\'\>)(.*)(?=\<\/div\>)/" *.html > output.txt

재귀적으로 작동하지만 정규식을 해석하지 않습니다. 대신 fgrep 또는 grep -f -r을 사용해 보십시오. 또한 touch output.txt> 대신 >>를 사용할 수도 있습니다.

관련 정보