我需要提取一堆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
和其他一些排列,仍然没有
不知道为什么你添加了所有这些花里胡哨的东西。这个简单的正则表达式对我有用:
你有六个问题:
/
在正则表达式的开头和结尾。您输入、和其他程序进行搜索,但您不需要它来搜索。而且,实际上,只会在模式中包含文字字符。/regex/
sed
vi
grep
grep
/
grep
,您必须使用-P
.-regexp
; 它必须是--regexp
。或者—regexp=
像在grep
.一旦我修复了上述错误,两个命令 (
grep -P
和) 都可以正常工作——但它们打印了包含模式的整行,包括 . 之前或之后的pcregrep
任何文本。<div …>
</div>
-o
.即使在我修复了它之后,我也得到了
<div …>
输出(但不是 之前的文本<div …>
,或者</div>
之后的任何内容)。所以,您的后视组有问题 - 它被包含在匹配中。
不幸的是,我对 PCRE 知之甚少,无法确切知道问题是什么或如何解决它。幸运的是,我知道的足够
pcregrep
多,知道一个解决方法。如果您的正则表达式中有多个捕获组,pcregrep
让您选择要写入输出的捕获组。所以,我们可以pcregrep
通过将look-behind变成一个捕获组,然后忽略它来让它起作用:但即使这样也比它需要的更复杂。第一个 (
<div …>
) 组不需要是捕获组;即,它根本不必是一个组。同样,最后一个组(</div>
前瞻组)根本不必是一个组。唯一需要成为一个组的是您要捕获的部分 -<div …>
和之间的部分</div>
:请注意,我更改
-o2
为-o1
是因为现在只有一组。顺便说一句,正如RudiC 发现的(但没有提到),这些反斜杠几乎都不是必需的。AFAICT,您唯一需要的是
\s
字符串中的那些;所以我们可以将上面的内容简化为:现在我们已经消除了正则表达式的所有 PCRE 部分(前瞻和后视),您可能认为我们可以将此正则表达式与 plain 一起使用
grep
。不幸的是,我们不能;上面的命令取决于没有的选项。-oN
grep
但是,我们可以将它与
sed
!与
pcregrep
命令一样,它会搜索整个正则表达式(包括 之前<div …>
或之后的内容</div>
,因为我.*
在开头和结尾添加了内容)并将其替换为 #1 捕获组(唯一的一个)。最后p
的 导致它打印匹配的行;该-n
选项导致它不打印不匹配的行。以上
|
用作正则表达式分隔符,因为正则表达式包含/
. 如果要/
用作分隔符,则必须转义文本/
(in</div>
):不幸的是,
sed
没有递归搜索功能。-r
选项sed
类似于; _-E
_grep
它指定了扩展正则表达式 (ERE) 的使用。没有它,我们将需要使用\(
and\)
捕获组:当然,您可以通过运行来进行递归
sed
搜索find
。PS 如果您在一行中有多个
<div …>
...对,这些命令将只打印第一个。</div>
sed
您正在执行错误的递归(目录树)搜索。
(
pcregrep
同样)查看每个.html
文件,然后查看名称以 . 结尾的任何目录中及其下 的每个文件。因此,如果(不太可能?)您有一个名为 的子目录,那么上述命令将搜索该目录中的每个文件(即使它被称为or )。如果(我认为更有可能)您有名称类似于and的子目录,则不会搜索它们。.html
foo.html
Makefile
README.txt
page42
index
你想做的是:
它对从
.
(当前目录)开始的所有目录进行递归搜索,只查看名称匹配的文件*.html
。正在递归工作,但不解释正则表达式。尝试使用 fgrep 或 grep -f -r。此外,您可能想要
touch output.txt
使用>> 而不是>。