在 for 循环中获取 awk 输出时遇到问题

在 for 循环中获取 awk 输出时遇到问题

我正在尝试创建一个脚本来检查网站上的单词。我有一些要检查,所以我尝试通过另一个文件输入它们。

该文件名为“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

相关内容