【发布时间】:2018-02-01 09:40:13
【问题描述】:
我正在处理来自curl -s 的输出。
具体来自这个页面:https://support.microsoft.com/en-us/help/971058/how-do-i-reset-windows-update-components
在我陈述我的目标之前,我会提到我只对从该页面的 curl 输出中提取所需数据的答案感兴趣。 (我知道此页面上建议的操作已经以文本、powershell 脚本等形式提供。)
最终目标是获取 dll 列表。 应该快速完成而不大惊小怪(所以单行),但现在它已成为我的学习经历。基本的正则表达式是/regsvr32.exe (.*?\.dll)/。
我感兴趣的 curl 输出看起来像这样(注意缺少换行符):
<li>regsvr32.exe a.dll</li><li>regsvr32.exe b.dll</li>etc
所以我尝试了 perl,如下所示:
perl -F"li" -lane 'print $1 if /regsvr32.exe (.*?\.dll)/g'
(逻辑是我可以在任何“li”出现时草率地拆分,并且仍然应该得到合理的结果,我可以稍后进行微调)
我根本无法让-F 工作。我尝试了单个字符,我尝试了像 /PATTERN/ 这样的正则表达式,我尝试省略各种其他标志(特别是 -l),我写了一个单行来显示拆分。我无法进行分裂。
然后我检查了 curl 手册页,看看它是否有任何可能有帮助的输出消毒剂。这是一个很长的手册页,但我什么也没看到。
然后我突然想到,如果我编写的 perl 能够正常工作,无论同一个正则表达式是否在同一行上多次匹配,那将是一件好事。但是我找不到任何适合单线的东西。
我能找到的最明智的方法是生成所需的单行输出:
curl -vs \
https://support.microsoft.com/en-us/help/971058/how-do-i-reset-windows-update-components 2>&1 | \
perl -pe 's|</li>|\n|g' | \
perl -lne 'print $1 if /regsvr32.exe (.*?\.dll)/'
谁能提出一些不那么荒谬的建议?
另外,我喜欢任何对 Perl 的 -F 参数的解释,它比 perldoc perlrun 更有启发性。
【问题讨论】:
-
不确定它是否更荒谬,但这里有一个替代方案(这可能远非最佳)。
curl -vs https://support.microsoft.com/en-us/help/971058/how-do-i-reset-windows-update-components 2>&1 | grep -Po 'regsvr32.exe (.*?\.dll)' | cut -d ' ' -f 2 -
您正在尝试使用单行中的简单正则表达式解析凌乱的 HTML。为什么不写一个漂亮的小脚本,比如HTML::TreeBuilder?这将是一件轻而易举的事。顺便说一句,您并没有真正说明您对“感兴趣”的具体内容——“看起来像这样”并没有让我明白。
-
@zdim 基本上是一个简单易用的解决方案。我试图澄清一下我的问题。一旦问题进入脚本领域,我倾向于切换到 C# 或 C++,只是因为我对这些语言更加熟悉。
-
当然,考虑到目标是什么(很好的编辑,谢谢),是确实可行,就像答案一样。但是请记住,由于所有这些出色的模块,某些类型的工作,例如解析 (X)HTML,使用脚本比使用 C++(我喜欢并使用 C++——不是抱怨这种语言)要简单得多。
-
@zdim - C# 对这些内置的东西有相当广泛的支持,但我怀疑 perl 或 python 让它更容易。 (当然不需要明确的编译步骤)。 Python 已经在我工作的地方使用了一点(并且往往出现在 Windows 机器上),但是 perl 解决了我的很多小问题,我很纠结该学哪一个。所以我在这两个方面都很糟糕:)