왜 내가 이것을 얻지 못하는지 잘 모르겠습니다. 몇 시간 동안 명령을 검색하고 테스트했지만 아무것도 발견하지 못했습니다.
텍스트는 다음과 같습니다
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><result expand="changes,testResults,metadata,logEntries,plan,vcsRevisions,artifacts,comments,labels,jiraIssues" key="EP-ED-JOB1-174" state="Failed" lifeCycleState="Finished" number="174" ....
그리고 저는 그 부분을 뽑아내고 싶습니다 . state="Failed"
아마도…state="Successful"
나는 백만 가지 변형을 시도했습니다.
sed '/state=".*"/p' htmlResponse.txt
그러나 대괄호, 이스케이프 슬래시 등은 전체 텍스트 블록과 일치하는 것 같습니다. 내 정규 표현식에 어떤 문제가 있나요?
답변1
"정규 표현식이 XML을 구문 분석하는 데 충분하지 않기 때문에 적절한 XML 구문 분석기를 사용해야 합니다."라는 필수 설명을 제쳐두고, sed
귀하의 행에 두 가지 문제가 있습니다.
".*"
"
.
일치하므로 처음부터 끝까지 일치합니다."
- 이
sed
명령은/.../p
인쇄합니다전반적으로정규식과 일치하는 경우.
빠르고 더러운 HTML 스크래핑 셸 스크립트를 위해 다음 두 가지 작업을 수행하는 것이 좋습니다.
"[^"]*"
"따옴표, 따옴표가 아닌 문자, 닫는 따옴표" 와 일치합니다 .grep -o
정규식과 일치하는 파일 부분을 추출하는 것이 훨씬 쉽습니다.
따라서 이것은 명령을 다음과 같이 만듭니다.
grep -o 'state="[^"]*"'
아니면 정말로~ 해야 하다sed를 사용하세요:
sed -n 's/.*\(state="[^"]*"\).*/\1/p'
답변2
올바른 방법은 다음과 같은 XML 파서를 사용하는 것입니다.xmlstarlet:
printf 'state="%s"\n' $(xmlstarlet sel -t -v "//result/@state" -n htmlResponse.txt)
산출:
state="Failed"
속성 값만 가져옵니다(노드가 result
두 개 이상인 경우 모든 노드에서).
xmlstarlet sel -t -v "//result/@state" -n htmlResponse.txt
답변3
전체 라인을 일치시켜 인쇄할 수도 있습니다.그냥 일치하는 그룹:
sed -r 's/.*state="([^"]*)".*/\1/' htmlResponse.txt
Failed
이것은 실제로 당신이 원하는 것이라고 생각되는 or Successful
( state=
이전 부분 제외) 을 꺼내는 것입니다 . 하지만 꼭 필요한 경우에는 쉽게 다시 추가하거나 약간 다른 정규식을 사용할 수 있습니다.우즈가 대답했듯이.
그러나 다음과 같이산딥이 언급됨, 이것은정규식을 사용하여 HTML(또는 XML)을 구문 분석하는 것은 단순히 신뢰할 수 없습니다.. 콘텐츠를 대화형으로 소비 grep
하거나 sed
검색하는 것도 중요하지만 이것이 중요한 작업을 수행해야 하는 스크립트의 일부인 경우그리고 실제로 일하다, XML을 올바르게 구문 분석해야 합니다.