如何使用Regex从html文档中提取特定元信息

时间:2018-04-10 11:16:29

标签: regex linux shell unix

我需要使用Linux命令从html文档中提取特定的元信息。

例如:具有

的html文档

<meta content="2017-12-26" name="lastmod"/>

我需要从此元标记中提取2017-12-26

我在'test'文件夹中有一组文章,我正在迭代以获取标题和元信息。

我能够获得标题,但不能获得元。

我正在尝试的代码

    DOC_FOLDER_PATH=test"/"

        for i in `find $DOC_FOLDER_PATH -type f -name "*.htm*"`
        do
          title_to_get=$(grep "<title>" $i | tail -1)
          title_to_get=$(echo $title_to_get | sed 's/<title>//g' | sed 's/<\/title>//g')
          echo "Title: "$title_to_get

          last_modify_date=$(grep "<meta name='lastmod' $i | tail -1)
          last_modify_date=$(echo $last_modify_date | sed 's/<meta//g' | sed 's/<\">>//g')
          echo 'content'$last_modify_date
        done

我收到title_to_get但不是last_modify_date。我如何获得last_modify_date

我希望我能够澄清这个问题。请帮帮我。

1 个答案:

答案 0 :(得分:1)

元标记中的内容和名称的顺序是免费的,但是您的表达式期望(<meta name='lastmod')lastmod是第一个,而它是第二个:

<meta content="2017-12-26" name="lastmod"/>

使用sed,您可以查看lastmod是否存在,然后选择内容内容:

echo '<meta content="2017-12-26" name="lastmod"/>'| sed -rn "/<meta .*name=.lastmod./ s/.*content=.([0-9-]+).*/\1/p"
2017-12-26

所以你的代码

last_modify_date=$(grep "<meta name='lastmod' $i | tail -1)
last_modify_date=$(echo $last_modify_date | sed 's/<meta//g' | sed 's/<\">>//g')

可以改进为

 last_modify_date=$(sed -rn "/<meta .*name=.lastmod./ s/.*content=.([0-9-]+).*/\1/p" "$i")

有一些陷阱需要提及:

也许下次的日期是2017/12/26。或者也许是经典的大陆形式26.12.2017。或其他众多其他格式之一。

模式“。([0-9 - ] +)。*”与单引号或双引号无关,可能完美无缺。但是你可以对有效字符进行分组并使用[“']进一步限制错误可能性content=2017-12-26,但我不确切知道,如何屏蔽这些字符以便你必须尝试。

使用换行符,你注定要失败:

<meta content="2017-12-26" 
      name="lastmod"/>

还有评论:

<!-- that's not longer valid:
    <meta content="2017-12-26" 
          name="lastmod"/>
-->

但通常只需检查您的结果就足够了,例如“确切地找到一个lastmod日期”,并对输入格式的更改作出反应。

大多数html页面并不完全符合标准,因此使用xml-parser也可能不起作用。但是看看xmlstarlet,如何解析xml。它一般非常有用,也可能有助于解决这个问题。