2016-10-22 197 views
-1
<div class="plot_summary minPlotHeightWithPoster"> 
      <div class="summary_text" itemprop="description"> 
        King Leonidas of Sparta and a force of 300 men fight the Persians at Thermopylae in 480 B.C. 
      </div> 

我想提取兩個div錨標記之間的文本。我是sed和awk的新手,所以我無法弄清楚如何做到這一點。我嘗試使用grep,但它不成功。使用sed,grep或awk提取兩個錨標記之間的文本

+1

禁用globbing每mklement0的評論加你試圖grep命令,它會告訴你已經嘗試過的東西...此外,這是最適合HTML解析器 – Sundeep

回答

2

由於Sundeep在評論中指出:最好使用合適的HTML解析器

標準公用事業主要是爲基礎,並與引用欠佳;他們沒有足夠的能力來強大地解析HTML,所有的變化都圍繞着引用樣式和空白,更不用說承認實際的語法了。

GNUgrep提供了比其它實施方式中更大的靈活性:多線匹配(-z),支持PCREs(-P),這使得能夠環視斷言。

雖然下面的GNU grep命令作品與樣品輸入,它仍然是遠不是一個強大的解析溶液:

grep -zPo '<div class="summary_text" itemprop="description">\s*\K.*?(?=\s*</div>)' file 
+0

非常感謝!:) –

+0

它給了一個錯誤,修改了一下grep -zPo'

\s*\K.*?(?=\s*
)',它的工作!謝謝:D –

+1

@SwastikUdupa:很高興聽到它的工作;重新錯誤:有趣 - 我沒有得到一個(GNU grep v2.22),但是你的調整是更簡單的解決方案,所以我已經用它更新了答案。 – mklement0

2

推薦方法在Unix或類Unix終端解析XML或HTML:

如果您正在尋找一種方法從unix命令行執行此操作,我建議首先考慮使用xml解析工具而不是awk,grep或sed。

例如,您的系統可能有xmllint。如果你的html包含在文件index.html中。下面xmllint命令的工作來提取文本:

xmllint --html --xpath "//div[contains(@class, 'plot_summary')]/div[contains(@class, 'summary_text')]/text()" index.html 

文本需要一個命令後,修剪所以你可能管到另一個命令做到這一點:

(xpath="//div[contains(@class, 'plot_summary')]/div[contains(@class, 'summary_text')]/text()" && \ 
xmllint --html --xpath "$xpath" index.html) \ 
| sed -e 's/^[[:space:]]*//' -e '/^[[:space:]]*$/d' 

這sed的命令,我們一舉超越輸出有兩個表達式。第一個在該行's/^[[:space:]]*//'的開始刪除空白和第二刪除該只是空白的任何行'/^[[:space:]]*$/d'

有你可以研究(見接受的答案)其他XML命令行分析器工具: How to execute XPath one-liners from shell?

使用sed的可怕方法:

您可以通過使用echo將文件分解成一行來解決sed的分析問題。然後使用sed替換你可以提取你想要的文本。這不是一個很好的方法,因爲它是一個非常格式相關方法:

(set -o noglob; echo $(cat index.html)) \ 
| sed 's/.*<div[^>]*class[^=]*=[^"]*"summary_text"[^>]*>[[:space:]]*\([^<]*\).*/\1/' 

更新通過set command

+2

++用於演示適當的解決方案。鑑於輸入是HTML,而不是XML,你應該使用'xmllint --html'。 在大多數情況下,normalize-to-single-line-beforehand方法可能沒有問題,只不過'echo $(cat ...)'是一個壞主意, 因爲文件中的標記受_globbing_支配。避免這個問題的一個足夠好的近似值是'tr -s'[:space:]''''; 作爲這個空白標準化步驟的替代方法,您可以循環在'sed'本身內建立整個輸入,並且在_GNU_'sed'的情況下只需使用'-z'。 – mklement0

+2

很好的評論!很多在那裏爲我學習。愛它 :)。當我在電腦上時,我會更新我的答案,並且可以將它們全部消化。在OSX上。開始認爲我應該研究獲取我最喜愛的命令的GNU副本。 ++也是你的方式。歡呼@ mklement0 –

+2

很高興聽到它,並感謝你。是的,使用GNU工具的生活要容易得多,但重要的是要知道什麼是GNU特有的,什麼不是在與其他平臺打交道時。我以前的評論的補充:'(set -f; echo $(cat index.html))'是解決不必要的globbing問題的實用解決方案(注意包圍子shell來定位'set -f'的效果)。 – mklement0

相關問題