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모든 줄 바꿈이 아닌 모든 공백에서 분할됩니다. 따라서 첫 번째 반복에서는 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}'`

그러면 많은 문제 중 하나가 해결될 것입니다.

답변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

관련 정보