我目前正在编写一个网络爬虫机器人。它生成一个 URL 列表,我需要它来删除重复项,并按字母顺序对行进行排序。我的代码如下所示:
#! /bin/bash
URL="google.com"
while [ 1 ]; do
wget --output-document=dl.html $URL
links=($(grep -Po '(?<=href=")[^"]*' dl.html))
printf "%s\n" ${links[@]} >> results.db
sort results.db | uniq -u
URL=$(shuf -n 1 results.db)
echo $URL
done
Run Code Online (Sandbox Code Playgroud)
特别是该行:
sort results.db | uniq -u
Run Code Online (Sandbox Code Playgroud)
POSIX说uniq -u:
禁止写入在输入中重复的行。
这意味着任何重复的行(甚至是原始行)都将被过滤掉。您的意思可能是(也用POSIX完成):
sort -u results.db
Run Code Online (Sandbox Code Playgroud)
对于sort -u,POSIX 说
唯一性:在每组具有相同键的行中抑制除一个之外的所有行。如果与 -c 选项一起使用,除了检查输入文件是否已排序外,还要检查是否没有带有重复键的行。
在任何一种情况下,以下行
URL=$(shuf -n 1 results.db)
Run Code Online (Sandbox Code Playgroud)
可能假设 sort/uniq 的目的是更新 results.db(它不会)。您必须为此稍微修改脚本:
sort -u results.db >results.db2 && mv results.db2 results.db
Run Code Online (Sandbox Code Playgroud)
或(如@drewbenn 所建议的),将其与上一行结合起来。但是,由于它附加到文件中(组合他的回答中显示的命令不会消除最新的 printf 和文件内容之间的重复项),单独的命令 sort/mv 看起来更接近原始脚本。
如果你想确保它$URL不是空的,那是(实际上是另一个问题),并通过[测试完成,例如,
[ -n "$URL" ] && wget --output-document=dl.html $URL
Run Code Online (Sandbox Code Playgroud)
虽然简单地退出循环会更简单:
[ -z "$URL" ] && break
Run Code Online (Sandbox Code Playgroud)