这是一个HTML文件,其中包含大量<section>... </section>
内容在一个HTML文件中,其格式如下。
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<section>
<div>
<header><h2>This is a title (RfQVthHm)</h2></header>
More HTML codes...
</div>
</section>
<section>
<div>
<header><h2>This is a title (UaHaZWvm)</h2></header>
More HTML codes...
</div>
</section>
<section>
<div>
<header><h2>This is a title (vxzbXEGq)</h2></header>
More HTML codes...
</div>
</section>
</body>
</html>
我需要提取第二个<section>...</section>
内容。
这是预期的输出。
<section>
<div>
<header><h2>This is a title (UaHaZWvm)</h2></header>
More HTML codes...
</div>
</section>
我注意到我可以先寻找UaHaZWvm
字符(前面 2 行),直到遇到下一个</section>
。
OP的努力(在评论中提到):grep -o "hi.*bye" file
这可以使用awk
,sed
或grep
工具完成吗?
由于您使用的是 HTML,因此使用可识别格式的工具(如xmllint
或其他一些允许您使用 XPath 表达式提取文档部分的程序)要简单得多,也更好:
$ xmllint --html --xpath '//section[2]' input.html 2>/dev/null
<section>
<div>
<header><h2>This is a title (UaHaZWvm)</h2></header>
More HTML codes...
</div>
</section>
(xmllint
给出了很多关于标签的错误;我不认为它真的支持HTML5?无论如何,这就是为什么上面有标准错误的重定向。
使用W3C的HTML-XML-utils程序集合中的hxselect
替代。它使用 CSS 选择器来指定要从文档中获取的内容,而不是 XPath:
hxselect 'section:nth-child(2)' < input.html
有了您显示的示例,您能否尝试以下操作。用GNUawk
编写和测试,应该可以在任何awk
工作。
awk '
/^</section>/{
if(found1==2 && found2==1){
print val
exit
}
found2++
}
/<section>/{
found1++
}
found1==2{
val=(val?val ORS:"")$0
}
' Input_file
说明:为上述添加详细说明。
awk ' ##Starting awk program from here.
/^</section>/{ ##Checking condition if line starts from </section> here.
if(found1==2 && found2==1){ ##Checking condition if found1 is 2 AND found2 is 1 then do following.
print val ##printing val here.
exit ##exiting from program from here.
}
found2++ ##Increasing found2 with 1 here.
}
/<section>/{ ##Checking condition if line has <section> then do following.
found1++ ##Increasing found1 with 1 here.
}
found1==2{ ##Checking if found1 is 2 then do following.
val=(val?val ORS:"")$0 ##Creating val and keep adding lines into it.
}
'
从您的问题中不清楚您是否尝试打印第 2 部分(无论它包含什么)或包含 UaHaZWvm 的部分(无论它以什么顺序出现),所以这里有两种解决方案:
要打印第 2 部分:
$ awk -v RS= -v ORS='nn' 'NR==3' file
<section>
<div>
<header><h2>This is a title (UaHaZWvm)</h2></header>
More HTML codes...
</div>
</section>
要打印包含UaHaZWvm
的任何部分:
$ awk -v RS= -v ORS='nn' '/UaHaZWvm/' file
<section>
<div>
<header><h2>This is a title (UaHaZWvm)</h2></header>
More HTML codes...
</div>
</section>
gawk '/<section>/,/</section>/{ s=s $0; }
/</section>/{ i++; print i, s; s=""; }
END{ if(s!="") print i,s}' some.html
将打印所有部分,例如:
1 <section><div><header><h2>This is a title (RfQVthHm)</h2></header>More HTML codes...</div></section>
2 <section><div><header><h2>This is a title (UaHaZWvm)</h2></header>More HTML codes...</div></section>
3 <section><div><header><h2>This is a title (vxzbXEGq)</h2></header>More HTML codes...</div></section>
这适用于Patterns
,请参阅来自 gawk 或 awk 的手册页。
只返回第二个应该很容易...
编辑:(基于Ed M的评论。
gawk '/<section>/{ i=(i<0?-i:i); i++; }
/</section>/{ i=-i; }
{ a[i]=a[i] $0 }
END{ print a[2] }' some.html
使用grep
您可以执行以下操作:grep 'UaHaZWvm' -B2 -A3 some.html
其中输出:
<section>
<div>
<header><h2>This is a title (UaHaZWvm)</h2></header>
More HTML codes...
</div>
</section>
在段落模式下使用awk
:
awk -v RS= -v ORS='nn' '/UaHaZWvm/' file
<section>
<div>
<header><h2>This is a title (UaHaZWvm)</h2></header>
More HTML codes...
</div>
</section>
更新我的解决方案,希望它对其他人有用。
这是结合grep
的解决方案,使用-B
选项设置内容的开头,使用-A
选项输出其余内容(通常10,000行就足够使用了),然后使用sed
或awk
来定位结束关键字。
awk
cat test.html | grep 'UaHaZWvm' -B2 -A10000 | awk 'NR==1,/</section>/'
塞德
cat test.html | grep 'UaHaZWvm' -B2 -A10000 | sed -n '1,/</section>/p'