Bash语法,用于下载链接文件和保留目录结构

时间:2018-07-21 00:15:32

标签: curl sed

我需要从网页下载所有特定类型的链接文件,例如pdf,然后根据站点结构将它们放在文件夹中。 我使用curl并将其与sed一起过滤以创建要下载的网址:

curl http://site/webpage | grep pdf | sort -u | sed 's/html code to exclude//' | sed 's/pdf">.*/pdf/' ~/urllist.txt

我使用以下方法创建文件夹:

sed -e 's#http.*com/##' | sed -e 's#/.*##' | sed -e '$!N; /^\(.*\)\n\1$/!P; D' < ~/urllist.txt > ~/dirlist.txt
cat ~/dirlist.txt | xargs mkdir

然后我可以下载它们,将所有文件放在一个文件夹中

cat ~/urllist.txt | xargs -n1 curl -O

所以我有两个问题:

  1. 我被mv命令所困扰。如何根据列表将下载的文件移动到文件夹?

  2. 我确信MacOS Sierra中有一个更加优雅的解决方案,它可以将所有命令组合在一个字符串中,而无需使用xcode / wget / homebrew / etc。我很高兴看到它。

各个URL看起来像http://site/folder/file.extension,例如https://cdn-10.nikon-cdn.com/pdf/manuals/dslr/D700_en.pdf

P.S。我知道wget可以使所有这一切都没有问题,但这不是一个选择,因为无法安装Xcode。

1 个答案:

答案 0 :(得分:0)

通过意识到sed将在必要时创建目录层次结构,可以大大简化mkdir -p脚本。实际上,这里不需要完整的正则表达式。替换非常简单,因此外壳程序的parameter expansion工具就足够了,

while read -r url; do
    # trim http://hostname/
    path=${url#http://*/}
    # remove last component
    dir=${path%/*}
    # create directories if necessary
    mkdir -p "$dir" || continue
    # dowload into dir
    ( cd "$dir"; curl -s "$url" )
done <urllist.txt

我们依靠的事实是,*在此上下文中始终与最短的字符串匹配。

如果URL包含目录名称中不允许的某些字符,

mkdir可能会失败(我隐约记得在MacOS上冒号是有问题的...?),如果发生这种情况,我们将跳过该URL(您应该会得到一个错误消息,其中包含来自mkdir的详细信息。)

curl在子shell中运行(这是括号的作用),因此我们可以cd到我们创建的目录,而无需在完成后返回cd。 (在某些极端情况下,这是不平凡的。)父脚本的工作目录不受子shell的影响。

我添加了一个-s选项,以减少curl的噪音;您显然可以根据需要再次将其删除,尽管这样做可能会导致在许多URL上运行该脚本时,可能会错过该脚本的任何错误消息。

此外,请注意,单个文件上的catuseless;您可以使用

将文件传递到xargs
xargs mkdir <dirlist.txt

但是,dirlist.txt不再有用或不必要。

您可能要在done之后删除重定向,并让脚本从标准输入中读取URL;请参阅第11页的『重新定向』。然后,您可以将URL生成器脚本直接传递到此下载器脚本中,而无需将URL保存在中间文件中。 (如果您仍然希望将该文件用于簿记或其他操作,请在管道的中间添加tee urllist.txt

./geturls |
tee urllist.txt |
./downloadurls

假设您将脚本摘要另存为具有这些名称和适当的shebang line,的文件,并将其标记为可执行文件。)