2012-10-17 1 views
1

우선,이 말을 해봅시다 :
regx'ing html은 나쁜 접근 방법으로 여겨집니다.하지만 척 노리스가 할 수 있다면, 왜 그럴 수 없습니까? ;)
이 html 페이지를 구문 분석하고 싶습니다. 세 개의 매개 변수를 기반으로 http://pastebin.com/unAifctF
을 기반으로합니다. 내가 시도 : (당신이 pixellany 감사) 228344 대신 228338
의 반환sed와 함께 여러 매개 변수에 따라 html에서 정수를 추출합니다

sed -n '/hebrew/{/DESPiTE/s/downloadsubtitle.php?id=/XXX/1};s/.*XXX\([0-9]*\).*/\1/p' 

와 나는 시도 : 228343 대신 228338 의 반환

sed -nr 's/.*downloadsubtitle.php\?id\=([0-9]+).*hebrew.*DESPiTE.*/\1/p' 

는 예상 된 결과이다 (당신에게 doubleDown 감사합니다) 228338 "downloadsubtitle.php \? id \ ="다음에 "hebrew"와 "DESPiTE"가 오는 첫 번째 숫자이기 때문에 무엇이 누락 되었습니까?

답변

1

이 = 도움이

희망)) :

sed -n '/[\x00\x01\x02]/q1;/hebrew/!b;s//\x01/;/DESPiTE/!b;s//\x02/;/downloadsubtitle.php?id=/!b;s//\x00/;s/.*\x00\([0-9]\+\)[^\x00\x01\x02]*\x01[^\x00\x01\x02]*\x02.*/\1/p' file 

Explanantion : 그래서 오류로 중단하면 선이, 구분 기호를 포함

  • /[\x00\x01\x02]/q1 확인 코드 1
  • /hebrew/!b;s//\x01/ 라인에 hebrew (n 라인 DESPiTE 포함 된 경우 구제하지 않을 경우 너무 \x02
  • /downloadsubtitle.php?id=/!b;s//\x00/ 체크 단일 문자로 단어 DESPiTE 번역 그래서 만약, 단일 문자에 \x01
  • /DESPiTE/!b;s//\x02/ 검사를 단어 hebrew 번역하면 라인이 downloadsubtitle.php?id= 경우가 포함되어있는 경우 OT는 구제 만일 그렇다면, 단어 downloadsubtitle.php?id=을 단일 문자로 번역하십시오. \x00
  • s/.*\x00\([0-9]\+\)[^\x00\x01\x02]*\x01[^\x00\x01\x02]*\x02.*/\1/p 원하는 번호를 인쇄하십시오.
+0

potong - 당신의 솔루션은 매력처럼 작동했습니다!감사 – buntuser

1

펄 솔루션 :

perl -nE ' 
    @fields = split /downloadsubtitle\.php\?id=([0-9]+)/; 
    for (1 .. $#fields) { 
     next unless $_ % 2; 
     say $fields[$_] if $fields[$_ + 1] =~ /hebrew.*DESPiTE/; 
    } 
' unAifctF.html 

는 어떻게 작동합니까? 그 사이에 숫자를 유지하면서 downloadsubtitle.php?id=XXX에 줄을 나눕니다. 다음 숫자 다음에 오는 문자열이 downloadsubtitle... 인 경우 hebrew 다음에 DESPiTE이 오는 숫자를 인쇄합니다.

+0

MAGIC! 고마워요! – buntuser

+0

"DESPITE"대신에 변수를 넣고 싶습니다 : perl -nE ' @fields = split /downloadsubtitle\.php\?id=([0-9]+)/; for (1 .. $ # fields) { 다음은 $ _ % 2; $ fields [$ _ + 1] = ~ /hebrew.*$var/ 인 경우 $ fields [$ _]; } 'unAifctF.html, 피곤하지만 작동하지 않습니다. 나는 그것을 벗어날 필요가 있습니까? – buntuser

+0

@buntuser : 변수에 특수 문자가 포함되어있는 경우에는 인용 부호로 묶어야합니다.'/ hebrew. * \ Q $ var \ E /' – choroba

0

문제는 *이 탐욕스러운 연산자이므로 최대한 많이 일치하므로 첫 번째 가능한 일치 항목이 아니라 마지막 가능한 항목과 일치하게됩니다. 따라서 일치 시키려고하는 내용을 변경해야합니다. 문제는 sed에서 어렵다는 또 다른 "downloadsubtitle.php? id ="를 제외하고는 무엇이든지 일치하도록하려는 것입니다. 당신이 적절한 스크립트를 원하는 경우

sed -nr 's/.*downloadsubtitle.php\?id\=([0-9]+)[^?]*hebrew[^?]*DESPiTE.*/\1/p' 

) = 당신이 중 하나는 더 복잡한 나오지도 스크립트를 작성하거나 링크와 제목 사이 ?의이 없을 것으로 가정 간단한 해결 방법을 사용할 수 있습니다

#!/bin/sed -nf 

: next 
$! { N; b next } 
s/\n//g 

s/downloadsubtitle\.php?id=\([0-9][0-9]*\)/\ 
\1/ 

: loop 
s/^[^\n]*\n// 

h 
s/\([0-9]*\).*/\1/ 
x 

s/downloadsubtitle\.php?id=\([0-9][0-9]*\)/\ 
\1/ 
/^[^\n]*hebrew[^\n]*DESPiTE/ { g; p; q } 
/^[0-9]*/ b loop 

이 스크립트는 전체 파일을 패턴 공간 (즉 작업 버퍼)으로로드하는 것으로 시작합니다. 이것은 처음 두 줄에서이 작업을 수행합니다. 첫번째 줄은 next이라는 레이블을 : "명령"으로 선언합니다. 두 번째 행은 명령으로 패턴 공간에 입력 된 다음 줄을 추가 한 다음 next 레이블로 점프하지만이 두 명령은 아직 마지막 행을 읽지 않은 경우에만 실행됩니다. 세 번째 행은 모든 개행 문자를 제거합니다.

이제는 downloadsubtitle\.php?id=[0-9][0-9]*의 첫 번째 발생 문자를 줄 바꿈 문자 (백 슬래시 뒤에 실제 줄 바꿈으로 표시)와 ID 번호로 바꿉니다.

새 레이블 loop이 만들어졌고 첫 번째 줄 바꿈 문자까지 모든 항목을 제거하기 때문에 (ID 앞의 모든 것을 제거합니다).

이제는 번호를 추출하여 보류 공간 (보조 버퍼)에 저장하는 일련의 명령이 있습니다. 먼저 h 명령을 사용하여 전체 패턴 공간을 보류 공간으로 복사 한 다음 숫자 뒤의 모든 것을 제거한 다음 보류 및 패턴 공간의 내용을 x으로 바꾸십시오. 이제 보류 공간에 숫자가 포함되고 패턴 공간이 해당 값으로 복원되었습니다.

욕심쟁이 검색을 방지하기 위해 다음 출현 downloadsubtitle\.php?id=[0-9][0-9]* 전에 개행 문자를 배치합니다. 개행 문자는 나머지 문자열을 찾았 기 때문에 ID 번호 만 남겨 둘 수 있습니다.

이제 검색 부분이 있습니다. 요약하면, 우리는 실제 ID를 홀드 공간에두고, 패턴 공간의 첫 번째 줄은 텍스트를 검색하고자하는 곳입니다. 그래서 우리는 버퍼 시작 부분부터 문자열 hebrewDESPiTE을 검색하는 검색 식을 사용합니다.이 검색 식은 서로 또는 새줄로 버퍼의 시작 부분에서 분리되지 않습니다. 따라서 첫 번째 행만 검색했습니다.

일치하는 것이 발견되면 g을 사용하여 보류 공간에서 ID를 가져오고 p을 인쇄 한 다음 q을 종료합니다.

일치하는 항목이 없으면 loop 레이블로 바로 이동하여 다음 발생을 검색합니다. 점프하기 전의 조건은 무한 루프를 방지하기위한 것입니다. 검색 할 내용이 없으면 종료됩니다. 당신 (GNU이 나오지 위해이 작동 할 수

관련 문제