forループからawk出力を取得する際に問題があります。

forループからawk出力を取得する際に問題があります。

Webサイトの単語を確認するスクリプトを作成しようとしています。私はいくつか確認したので、別のファイルからインポートしようとしました。

ファイル名は「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すべての改行ではなく、すべてのスペースで分割されます。したがって、最初の反復ではthenなどに$DATAなります。また、各値はワイルドカード拡張を受けているため、キーワードに存在する場合、現在のディレクトリにあるファイルによっては奇妙な結果が表示されることがあります。ExampleDomains;www.example.com*

誰ですか改行で区切られたデータを処理してみてください。。簡単な方法は

while read -r keyurl; do
done <testurls

これにより、各行のインデントが削除されます。これはおそらくここでは悪いことではありません。 (正確にすべての行を含めIFS= read -r keyurlたい場合にkeyurl使用します。)

ファイル名で渡すため、呼び出しはawk機能しません。$keyurl入力として渡す必要があります。これを行うときは、常に変数置換の周りに二重引用符を使用してください(そうしないと、シェルはその値に対していくつかの拡張を実行します)。$(…)代わりに使用することをお勧めします。内部で何かを参照したい場合は、使用するのがより困難ですが、構文は`…`直感的です。`…`$(…)

keyword=`echo "$keyurl" | awk -F ";" '{print $1}'`
url=`echo "$keyurl" | awk -F ";" '{print $2}'`

最初のセミコロンで変数を分割するより良い方法があります。つまり、シェルの組み込み構成を使用して、文字列からプレフィックスまたはサフィックスを削除します。

keyword=${keyurl%%;*} url=${keyurl#*;}

ただし、データはread組み込みデータから取得され、区切り文字は単一文字であるため、IFS読み込み中にその機能を活用して入力を直接分割できます。

while IFS=';' read -r keyword url; do …

$keywordカールとgrep呼び出しを実行するときは一重引用符を使用するので、リテラルテキストを見つけることに注意してください。二重引用符を使用してください。このキーワードは次のように解釈されます。基本正規表現。キーワードをリテラル文字列として解釈するには、-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値を処理するデータファイルとして扱います。 awkに$ keyurl値を指定する必要があります。

keyword=`echo $keyurl | awk -F ";" '{print $1}'`

これにより、多くの問題の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

関連情報