以下是我想做的事情:
- 下载网页
- 查找其中所有与正则表达式匹配的字符串
- 在 URL 前面添加或附加字符串常量,以形成完全限定的 URL
- 全部下载
这应该很容易!用curl
管子grep
串起来就足够了,但我做不到!
curl http://example.com/?q=blah | grep -o -P "(?<=alt=\")[^\"]*\"" | what's next?
此外,grep 似乎无法识别[^\"]
。
DownThemAll! 之类的东西不够灵活。
答案1
我放弃了 grep。希望 perl 解决方案可以。
卷曲http://example.com/?q=blah| perl -e ' @alt=map { /alt="(.*?)"/ig } ; 打印 "$_\n" foreach(@alt)'
给出这个输入:
afk alt="<I want to find this>" easdfg alt="<I want to find that>"
adsfsgw wt er ger
ekfj er alt="<I want to find this other>" alt="<I want to find this anotherthing>" fgerg
ey
ty rth
<img src="file.gif">
它返回这个:
<I want to find this>
<I want to find that>
<I want to find this other>
<I want to find this anotherthing>
答案2
我注意到很多内容都使用了双引号,因此我猜它是在 cmd.exe 中完成的(尽管许多 Linux 用户使用 grep,但还有 Windows 版本。我欢迎对此提出任何纠正,但您的示例在我看来像是针对 Windows 实现的,因为您使用了双引号。我也在使用 Windows 实现的 grep - gnuwin32 实现。(例如,与 cygwin 实现相反)。
首先,我想纠正您在 grep 中使用的行中的错误(我不会将其称为正则表达式中的错误,因为这是一个 cmd 问题。
这是您的正则表达式与 grep 不起作用的示例。
curl http://example.com/?q=blah | grep -o -P "(?<=alt=\")[^\"]*\"" | what's next?
正如你所说,[^\"]
不起作用
让我们看看 cmd 到底传递给 grep 的是什么(grep 正在解析什么)
这将需要一个 C 程序,该 C 程序包含在有关引用不起作用的这个问题中让这个简单的正则表达式在 grep 中匹配
我将在这里粘贴 C 程序的代码。
您可以使用此程序查看 grep 或任何 Windows 程序接收到的内容。(我在这里可能在某些技术细节上是错误的,如果是这样,我欢迎纠正)。话虽如此,但这确实有效。
下面是我们将用来判断发生了什么的程序
#include <stdio.h>
int main(int argc, char *argv[]) {
int i = 0;
while (argv[i]) {
printf("argv[%d] = %s\n", i, argv[i]);
i++;
}
return 0;
}
我已经将它编译为 wc ,到 w.exe
这是一个正在发生事情的简单例子。
这是一个有效的例子
W:\>w "[^\"]"
argv[0] = w
argv[1] = [^"]
W:\>
如上所示,我们的程序 (w) 有 2 个参数,第一个是程序 (w) 的名称,第二个是 [^"]
现在这里有一个小得多的例子,有和你一样的失败,[^\"]
不起作用
W:\>w "\"[^\"]"
argv[0] = w
argv[1] = "["]
W:\>
看看 grep 得到了什么。我不知道为什么……但看起来,当 \" 在 [^\"] 之前,并且整个东西周围都有双引号时,[^\"] 不起作用,我们看到的结果正是 [^\"] 变成 ["] 我们失去了插入符号 ^
这将保留我们的插入符号,正如我们在程序中看到的那样。
W:\>w "\"[^^\"]"
argv[0] = w
argv[1] = "[^"]
W:\>
除了 Windows 问题之外,您的正则表达式也存在问题,您可能希望先行查找引号,因此您无法匹配末尾的引号。您正确地包含了后行查找,以便无法匹配起始引号。
举个例子
W:\>echo blah alt="test" | grep -o -P "(?<=alt=\")[^^\"]*(?=\")"
test
假设我们有一个名为 aa 的文件
dsfsdf dfdsf alt="here" dddd
rrtrtdfddalt="there"dfdfd
alt="df"
tree="dop"
现在我们申请
W:\>grep -oP "(?<=alt=\")[^^\"]*(?=\")" a.a
here
there
df
W:\>
因此,正则表达式和 grep 一样有效。
W:\>grep -oP "(?<=alt=\")[^^\"]*(?=\")" a.a
here
there
df
W:\>
现在假设我可以将其输出到文件。ab,所以 ab 现在包含这 3 行。(您可以随时将其复制/粘贴到 ab 中)
现在 ab 有
here
there
df
让我们使用 sed 在前面和后面添加一些
W:\>sed -r "s#(.*)#http://blah.com/\1.htm#" a.b
http://blah.com/here.htm
http://blah.com/there.htm
http://blah.com/df.htm
W:\>
我们可以用 wget 下载所有这些
W:\>sed -r "s#(.*)#http://blah.com/\1.htm#" a.b >a.c
W:\>type a.c
http://blah.com/here.htm
http://blah.com/there.htm
http://blah.com/df.htm
W:\>wget -i a.c
--2012-07-26 23:21:06-- http://blah.com/here.htm
Resolving blah.com... ^C
W:\>
答案3
检查wget -r -A.pdf [url]
简单模式。这将递归地从 [url] 下载所有 pdf。文档中的这个片段很有用。
'-A acclist --accept acclist' '-R rejlist --reject rejlist' 指定要接受或拒绝的文件名后缀或模式的逗号分隔列表(请参阅文件类型)。请注意,如果任何通配符“*”、“?”、“[”或“]”出现在 acclist 或 rejlist 的元素中,它将被视为模式,而不是后缀。