我试图在下载的网页中找到一个字符串curl
。我用来查找与正则表达式grep
模式匹配的字符串。
以下是我试图找到的字符串:
./download/file.php?id=86753
该字符串是网页中这个较大字符串的一部分:
href="./download/file.php?id=86753"
我正在使用的咒语grep
如下:
grep -Eo '\.\/download\/file\.php\?id=[0-9]+' dlfile.html
但这在 html 文件中找不到任何内容。但是,如果我进行grep
如下修改,我会得到两 (2) 个匹配项。第一场比赛就是我需要的;第二个是无用的干扰,不得包含在内:
grep -Eo '\/download\/file\.php\?id=[0-9]+' dlfile.html
/download/file.php?id=86753
/download/file.php?id=62517
包含第二个(不需要的)匹配的字符串如下:
href="https://web.archive.org/web/20190824162104/https://www.somewhere.com/forums/download/file.php?id=62517&sid=907ab04af81e19ad758c5bcf8ebdca32"
问题似乎是无法识别.
字符串中的前导(点)。请注意,这是所需字符串和不需要的字符串之间的主要区别。
问:为什么这不起作用,我需要什么?
我的环境:Debian 衍生品(Raspberry Pi),“bullseye”版本
grep
我正在使用哪个bash
?
$ grep --version
grep (GNU grep) 3.6
...
$ bash --version
GNU bash, version 5.1.4(1)-release (arm-unknown-linux-gnueabihf)
您已经使用过
grep -E
,需要扩展正则表达式(ERE)。点必须始终作为文字进行转义。问号对于 ERE 来说是有效的运算符,因此为了匹配文字,它也必须被转义:你问,
您的模式匹配并且需要一个文字点(这就是
\.
意思)。但是,您在问题中描述的字符串不会出现在您尝试搜索的网页中。grep
不忽视它;它强制要求这样做。看:我假设您想要其中第一个,所以让我们提取其中一个:
如果您只想要以开头的部分,
/download
您可以轻松地将其剥离如果您确实想使用
grep
而不是正确的工具来完成工作,这将返回相同的结果:您的主题行中问题的答案:
很简单——事实并非如此。
使用您在 1 个文件中一起提供的 2 条示例输入行:
并删除 s 之前不需要的(可能无害但肯定依赖于每个 POSIX 的未定义行为)反斜杠,然后运行问题中的
/
2 个命令:grep
第一个
grep
包含前导.
,仅匹配输入中具有前导的字符串,.
而第二个grep
不包含前导.
,毫不奇怪地匹配输入中不以 a 开头的 2 个字符串.
。关于您对上述第一点的评论
grep
:然后:
因此,当我们不知道您的命令是什么样子或者我们不知道您的输入是什么样子时,我们实际上无能为力来帮助您调试用于解析某些输入的命令。
这里已经有很多评论了。其中一些人提出了合理的担忧和问题。我相信我终于解决了这个问题,我将其发布在这里以期结束。
您可能已经了解到,我正在“抓取”包含我需要的信息项的字符串的 URL。大概两年前,我开发了一个脚本来“自动化”这项任务,而且运行得非常完美。该脚本主要完成两件事:
curl
&grep
网页grep
行动几天前“有些事情发生了变化” 。我的“可靠”脚本在每次运行期间都开始抛出错误;错误指示表明
grep
未能找到该字符串。我grep
正在使用的:到目前为止,我仍然不知道一切都发生了变化。我认为其中一个变化是该网站已外包给一家名为“CloudFlare”的公司;另一个似乎是他们不再像处理
curl
浏览器下载那样处理下载。其他变化似乎正在发生。我的问题所反映的混乱部分是由于这些网站的变化,但主要是由于我。我应该有耐心,在发布问题之前更彻底地调查错误。我向所有相关人员致歉。
我声称从这次经历中学到了一件事:
grep
不是解析 HTML 的正确工具。我有两个参考资料可以分享:这个有争议的线程来自 SO re using regexes to parse HTML
Hiks Gerganov 的这篇内容丰富的文章标题为“在 Shell 中提取 HTML 标签之间的文本的 HTML 解析”。
如果我更改
\/
为 plain ,这里工作正常/
:输出:
您还可以考虑
\B
在开头和\b
结尾添加,以便更好地拒绝不需要的未遂事件。