我正在尝试创建一个脚本来检查网站上的单词。我有一些要检查,所以我尝试通过另一个文件输入它们。
该文件名为“testurls”。在文件中,我列出了关键字,然后列出了 URL。它们之间用分号分隔。
Example Domains;www.example.com
Google;www.google.com
这是脚本:
#!/bin/bash
clear
# Call list of keywords and urls
DATA=`cat testurls`
for keyurl in $DATA
do
keyword=`awk -F ";" '{print $1}' $keyurl`
url=`awk -F ";" '{print $2}' $keyurl`
curl -silent $url | grep '$keyword' > /dev/null
if [ $? != 0 ]; then
# Fail
echo "Did not find $keyword on $url"
else
# Pass
echo $url "Okay"
fi
done
输出是:
awk: cannot open Example (No such file or directory)
awk: cannot open Example (No such file or directory)
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
Did not find on
awk: cannot open Domains;www.example.com (No such file or directory)
awk: cannot open Domains;www.example.com (No such file or directory)
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
Did not find on
awk: cannot open Google;www.google.com (No such file or directory)
awk: cannot open Google;www.google.com (No such file or directory)
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
Did not find on
我已经研究这个问题很多年了。非常欢迎任何帮助。
答案1
您的脚本存在几个问题。我列出了我发现的,但我还没有测试过,可能还有其他。
for keyurl in $DATA; do …
$DATA
在每个空格处分割,而不是在每个换行处分割。所以在第一次迭代中,$DATA
将是Example
;然后Domains;www.example.com
,等等。此外,每个值都会经历通配符扩展,因此如果关键字中有 a *
,您可能会看到奇怪的结果,具体取决于当前目录中存在的文件。
你是尝试处理换行符分隔的数据。一个简单的方法是
while read -r keyurl; do
…
done <testurls
这会去除每行的缩进,这在这里可能不是一件坏事。 (IFS= read -r keyurl
如果您想keyurl
精确包含每一行,请使用。)
您的调用awk
不起作用,因为您是$keyurl
作为文件名传递的。您需要将其作为输入传递。当您执行此操作时,请始终在变量替换周围使用双引号(否则 shell 会对它们的值执行一些扩展)。我还建议使用$(…)
而不是`…`
;它们是相同的,只是`…`
当您想引用内部内容时很难使用,而 的语法$(…)
很直观。
keyword=`echo "$keyurl" | awk -F ";" '{print $1}'`
url=`echo "$keyurl" | awk -F ";" '{print $2}'`
有一种更好的方法可以在第一个分号处分割变量:使用 shell 的内置构造从字符串中去除前缀或后缀。
keyword=${keyurl%%;*} url=${keyurl#*;}
但由于您的数据来自read
内置数据并且分隔符是单个字符,因此您可以利用该IFS
功能并在读取时直接拆分输入。
while IFS=';' read -r keyword url; do …
在进行curl 和grep 调用时,请注意您正在寻找文字文本$keyword
,因为您使用了单引号。使用双引号;请注意,该关键字将被解释为基本正则表达式。如果您希望将关键字解释为文字字符串,请将-F
选项传递给grep
。您还应该放在-e
模式之前,以防关键字以字符开头-
(否则关键字将被解释为 grep 的选项)。最后说到 grep 的话题,它的-q
选项相当于>/dev/null
.还要记住 周围的双引号$url
。
curl -silent "$url" | grep -Fqe "$keyword"
您可以if [ $? != 0 ]; then
通过直接将命令放入其中来缩短该部分。
if curl -silent "$url" | grep -Fqe "$keyword"; then
总之;
while IFS=';' read -r keyword url; do
if curl -silent "$url" | grep -Fqe "$keyword"; then
echo "Did not find $keyword on $url"
else
echo $url "Okay"
fi
done
答案2
awk 正在将 $keyurl 的值视为要处理的数据文件。您需要将 $keyurl 的值提供给 awk,例如
keyword=`echo $keyurl | awk -F ";" '{print $1}'`
这将解决您的众多问题之一。
答案3
如果格式testurls
一致,可以使用更简单的方法:
#!/bin/bash
while read -r line; do
keyword="${line%;*}"
url="${line#*;}"
curl -silent "$url" | grep "$keyword" >/dev/null
[ $? = 0 ] && echo "${keyword} found" || echo "Fail..."
done < testurls