查找文件中的文本并复制到 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

你有六个问题:

  1. /在正则表达式的开头和结尾处包含了内容。您输入、和其他程序来进行搜索,但不需要它。事实上,只会在模式中包含文字字符。/regex/sedvigrepgrep/
  2. 要在 (plain) 中使用 PCRE grep,您必须使用-P.
  3. 不存在这样的事情-regexp;它一定要是--regexp。或者省略 并将—regexp=正则表达式作为朴素的参数给出,就像在 中所做的那样grep

一旦我修复了上述错误,两个命令 (grep -Ppcregrep) 都可以工作 - 但它们打印了包含模式的整行,包括 . 之前<div …>或之后的任何文本</div>

  1. 要仅打印与模式匹配的文本,您必须指定-o

即使我解决了这个问题,我还是<div …>在输出中得到了(但不是之前的文本<div …>,或者</div>之后的任何内容)。所以,

  1. 您的后视组出现问题 - 它被包含在比赛中。

    不幸的是,我对 PCRE 的了解不够,无法确切地知道问题是什么或如何解决它。幸运的是,我了解得足够多,pcregrep知道解决方法。如果您的正则表达式中有多个捕获组, pcregrep您可以选择要写入输出的捕获组。因此,我们可以pcregrep 通过将后视转换为捕获组,然后忽略它来使其工作:

    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 …>或之后的内容</div>,因为我.*在开头和结尾添加了内容)并将其替换为 #1 捕获组(唯一的一个)。末尾的p导致它打印匹配的行;该-n选项导致它不打印不匹配的行。

    上面用作|正则表达式分隔符,因为正则表达式包含/.如果您想用作/分隔符,那么您必须转义文本/(在 中</div>):

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

    不幸的是,sed没有递归搜索功能。选项类似于;-r​​它指定扩展正则表达式 (ERE) 的使用。如果没有它,我们需要使用and作为捕获组: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,那么上面的命令将搜索每一个该目录中的文件(即使它被称为Makefileor 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使用 >> 而不是 >。

相关内容