웹사이트의 단어를 확인하는 스크립트를 작성하려고 합니다. 확인할 것이 몇 가지 있어서 다른 파일을 통해 가져오기를 시도해 보았습니다.
파일 이름은 "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
됩니다. 또한 각 값은 와일드카드 확장을 거치므로 키워드에 이 있는 경우 현재 디렉터리에 있는 파일에 따라 이상한 결과가 나타날 수 있습니다.Example
Domains;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