在文件中查找文本並複製到 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
和其他一些排列,仍然沒有
不知道為什麼你添加了所有這些花里胡哨的東西。這個簡單的正則表達式對我有用:
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>
你有六個問題:
- 您包括
/
在正則表達式的開頭和結尾。您輸入、和其他程序進行搜尋,但您不需要它來搜尋。而且,實際上,只會在模式中包含文字字元。**/***regex***/**``sed``vi``grep``grep``/
- 要在 (plain) 中使用 PCRE
grep
,您必須使用-P
.- 沒有這樣的事情
-regexp
; 它必須是--regexp
。或者—regexp=
像在grep
.一旦我修復了上述錯誤,兩個命令 (
grep -P
和) 都可以正常工作——但它們列印了包含模式的整行,包括 . 之前或之後的pcregrep
任何文本。<div …>``</div>
- 要僅列印與模式匹配的文本,您必須指定
-o
.即使在我修復了它之後,我也得到了
<div …>
輸出(但不是 之前的文本<div …>
,或者</div>
之後的任何內容)。所以,
- 您的後視組有問題 - 它被包含在匹配中。
不幸的是,我對 PCRE 知之甚少,無法確切知道問題是什麼或如何解決它。幸運的是,我知道的足夠
pcregrep
多,知道一個解決方法。如果您的正則表達式中有多個擷取組,pcregrep
讓您選擇要寫入輸出的擷取組。所以,我們可以pcregrep
通過將look-behind變成一個擷取組,然後忽略它來讓它起作用:pcregrep -o **2** -r "(\<div\sclass\=\'cls\s\'\>)(.*)(?=\<\/div\>)"
但即使這樣也比它需要的更複雜。第一個 (
<div …>
) 組不需要是擷取組;即,它根本不必是一個組。同樣,最後一個組(</div>
前瞻組)根本不必是一個組。唯一需要成為一個組的是您要擷取的部分 -<div …>
和之間的部分</div>
:pcregrep **-o1** -r "\<div\sclass\=\'cls\s\'\>(.*)\<\/div\>"
請注意,我更改
-o2
為-o1
是因為現在只有一組。順便說一句,正如RudiC 發現的(但沒有提到),這些反斜杠幾乎都不是必需的。AFAICT,您唯一需要的是
\s
字元串中的那些;所以我們可以將上面的內容簡化為:pcregrep -o1 -r "<div\sclass='cls\s'>(.*)</div>"
現在我們已經消除了正則表達式的所有 PCRE 部分(前瞻和後視),您可能認為我們可以將此正則表達式與 plain 一起使用
grep
。不幸的是,我們不能;上面的命令取決於沒有的選項。-o*N*``grep
但是,我們可以將它與
sed
!sed -n -r "s|.*<div\sclass='cls\s'>(.*)</div>.*|\1|p"
與
pcregrep
命令一樣,它會搜尋整個正則表達式(包括 之前<div …>
或之後的內容</div>
,因為我.*
在開頭和結尾添加了內容)並將其替換為 #1 擷取組(唯一的一個)。最後p
的 導致它列印匹配的行;該-n
選項導致它不列印不匹配的行。以上
|
用作正則表達式分隔符,因為正則表達式包含/
. 如果要/
用作分隔符,則必須轉義文本/
(in</div>
):sed -n -r "s **/** .*<div\sclass='cls\s'>(.*)< **\/** div>.* **/** \1 **/** p"
不幸的是,
sed
沒有遞歸搜尋功能。-r
選項sed
類似於; _-E
_grep
它指定了擴展正則表達式 (ERE) 的使用。沒有它,我們將需要使用\(
and\)
擷取組:sed -n "s/.*<div\sclass='cls\s'> **\(** .* **\)** <\/div>.*/\1/p"
當然,您可以通過執行來進行遞歸
sed
搜尋find
。PS 如果您在一行中有多個
<div …>
…對,這些命令將只列印第一個。</div>``sed
6. 您正在執行錯誤的遞歸(目錄樹)搜尋。grep -r*正則表達式**.html
(
pcregrep
同樣)查看每個.html
文件,然後查看名稱以 . 結尾的任何目錄中及其下 的每個文件。因此,如果(不太可能?)您有一個名為 的子目錄,那麼上述命令將搜尋該目錄中的每個文件(即使它被稱為or )。如果(我認為更有可能)您有名稱類似於and的子目錄,則不會搜尋它們。.html
foo.html``Makefile``README.txt``page42``index
你想做的是:
grep -r --include='*.html'*正則表達式*。
它對從**
.
**(目前目錄)開始的所有目錄進行遞歸搜尋,只查看名稱匹配的文件*.html
。