如何执行正则表达式匹配并输出匹配项

如何执行正则表达式匹配并输出匹配项

我正在从 URL 列表中对网站执行链接检查,我能想到的唯一方法是使用 wget:,wget --server-response -i inputfile 2> output然后进一步解析标头响应。这会为大型列表输出一个相对较大的文件,我只想知道是否存在 404。典型的响应如下所示:

--2017-03-28 19:14:39--  https://www.example.com/foo/bar
Reusing existing connection to www.example.com:443.
HTTP request sent, awaiting response... 
  HTTP/1.1 404 NotFound
<snip>

我如何才能对每个 url(来自 stderr)的 wget 输出执行正则表达式匹配,并且如果存在 404 则输出该 url,然后我可以将其重定向到一个文件,这样我就剩下一个包含 404 列表的文件?(请不要建议使用 curl,不幸的是该网站设置为返回METHOD NOT ALLOWED

答案1

怎么样

#!/bin/bash

URLLIST=/path/to/file

for each in `cat $URLLIST`
do
   IS404=`wget -S "$each" -O /dev/null 2>&1 | grep "HTTP/1.1 404" | wc -l`

    if [ $IS404 -gt 0 ]
    then
        echo $each
    fi
done

我只对上述内容进行了部分测试,但关键行(以 IS404 开头)对每个 URL 执行 wget(因为它在 for each 循环中),丢弃输出,重定向标准输出(这就是 2>&1 所做的),因此将标头(感谢 -S)重定向到 stdout,然后计算 404 响应的数量。如果找到一个或多个,它会打印 URL。

答案2

抱歉,最初我错过了“不建议卷曲”警告。但你仍然可以从这篇文章中获得一些东西……

这样做的方法是使用卷曲. 如果你收到回复方法不允许,同样的答复必须包含允许的方法列表。你也许可以发布它。有时得到方法是不允许的,而方法是允许的;其他时候,反之亦然。唯一知道的方法是检查答复。我的猜测你尝试过得到方法,并自动得出结论,方法 (IE(仅下载标头)同样被禁止。不一定如此,有时管理员会禁止 GET 以避免其有限的连接资源过载,但他们会允许 HEAD。无法知道先验

卷曲的优点:

  1. 卷曲可以告诉它只下载标题,从而放弃(在这种情况下)无用的实际页面下载;只需尝试:

    curl -I http://www.debian.org
    
  2. 卷曲自动保持连接打开一段默认时间(900 秒,我思考):

    # curl -v http:://www.debian.org -I www.debian.org
      ......
      * Connection #0 to host www.debian.org left intact
    

    这是默认选项,但为了安全起见,手册声明你可能如果你愿意,可以使用- 活着选项。

为了进一步加快速度,您可能希望并行化卷曲

URL_LIST=$(cat inputfile)
echo $URL_LIST | xargs -n 1 -P 8 -I{} bash -c 'curl -I {} 2>1 | grep 404 &>/dev/null ; [ $? ] && echo {}'

这将逐个传递 URL 名称(-n 1)最多 8 个在平行下-P 8)到以下命令,当且仅当404代码。选项-我{}告诉 xargs 将选定的 URL 名称放在何处。所有输出都将被丢弃,因为所需的只是最后一个命令的退出代码,grep

根据您的具体需求,还有更多可能的调整:选项列表卷曲非常巨大。

答案3

你可以安装 powershell https://github.com/PowerShell/PowerShell

然后,您可以轻松编写一个强大的脚本来检查 URL 是否断开,并执行诸如发送电子邮件之类的操作: https://stackoverflow.com/questions/18500832/script-to-check-the-status-of-a-url

Foreach($Uri in $URLList) {
  $error.Clear()

  $time = Measure-Command { $request = Invoke-WebRequest -Uri $uri } 2>$null

  if ($error.Count -eq 0) {
    $time.TotalMilliseconds
  } else {
    $error[0].Exception.Response
  }
}

相关内容