如果我在命令行中复制/粘贴此内容,我可以在 2015 年 1 月 1 日的 24 小时内下载所有 GitHub 存档文件:
wget http://data.gharchive.org/2015-01-01-{0..23}.json.gz
我希望能够使用脚本连续几天执行此操作。例如,在我的 .sh 文件中:
#!/bin/bash
while read line
do
wget $line
done < download_github_files.txt
在 中download_github_files.txt
,我有:
http://data.gharchive.org/2015-01-01-{0..23}.json.gz
http://data.gharchive.org/2015-01-02-{0..23}.json.gz
http://data.gharchive.org/2015-01-03-{0..23}.json.gz
不幸的是,当我运行.sh 文件时,我得到了三份打印输出:
--2019-02-27 19:00:28-- http://data.gharchive.org/2015-01-01-'%7B'0..23'%7D'.json.gz
Resolving data.gharchive.org (data.gharchive.org)...
Connecting to data.gharchive.org (data.gharchive.org)...
connected.
HTTP request sent, awaiting response... 404 Not Found
2019-02-27 19:00:28 ERROR 404: Not Found.
问题显然出在{
。转义该字符没有帮助,因为据我所知,它应该是一个迭代器。
我如何使用下载这些文件wget
?
编辑:
嗯。我遇到了同样的问题,尝试使用第一个发布的解决方案:
.sh 文件(显然我要处理一年中的所有月份,但是为了便于可视化,我将范围限制为二月):
#!/bin/bash
for i in {01..12}; do
if [ ${i} = 02 ]; then
for j in {01..28}; do
for k in {0..23}; do
wget http://data.gharchive.org/2011-${i}-${j}-${k}.json.gz
done
done
fi
done
同样的问题。例如,我得到:
--2019-02-27 20:50:05-- http://data.gharchive.org/2011-02-01-5.json.gz
Resolving data.gharchive.org (data.gharchive.org)...
Connecting to data.gharchive.org (data.gharchive.org)...
HTTP request sent, awaiting response... 404 Not Found
2019-02-27 20:50:05 ERROR 404: Not Found.
但如果我运行命令
wget http://data.gharchive.org/2011-02-01-5.json.gz
那么我就没问题了。我可以手动下载文件,但无法在 bash 脚本中执行此操作。还有其他想法吗?
答案1
只需将其放入迭代器循环wget
中for
,如下所示:
#!/bin/bash
for i in {1..23}; do
wget http://data.gharchive.org/2015-01-01-${i}.json.gz;
done
答案2
括号扩展发生在变量扩展之前,因此分配给的括号$line
不会被扩展。
这应该有效:
eval wget $line
whereeval
再次评估该行。此时$line
已经展开,并且 shell 评估的行类似于您的第一个命令:
wget http://data.gharchive.org/2015-01-01-{0..23}.json.gz
但谨防!类似这样的条目
foo; rm -rf /some/precious/directory
在download_github_files.txt
文件中将导致以下行评估:
wget foo; rm -rf /some/precious/directory
“评估”意味着;
执行单独的命令(而如果没有这个eval
,它将只是传递给的参数的一部分)。;
$line
foo;
wget
看为什么eval
在 Bash 中应避免使用,以及我应该使用什么来代替?我怀疑此链接不包含任何您可以轻松使用的eval
内容特别的这种情况,但它仍然揭示了一些一般性问题。eval
仅当文件包含您完全控制的行并且您确定它们将毫无意外地被评估时才使用。