2010-07-20 64 views
2

我正在尝试编写一个bash脚本,它可以让我使用curl下载多个网页。对于每个网页,我希望能够通过卷页和引用链接。我希望能够一次提供多个网页。是否有可能使用bash访问for循环中的多个数组

换句话说,我希望能够遍历我提供脚本的网页,并为每个页面传递关联的网页和引用链接来卷曲。

我以为我会用一个数组来存储单个变量中的网页和引用链接,因为我认为在运行curl时可以提取数组中的单个元素。

我的问题是,我无法弄清楚如何让多个数组在for循环中正常工作。这是我想要做的一个想法。此代码不起作用,因为“$ i”(在for循环中)不会成为数组。

#every array has the information for a separate webpage 
array=("webpage" "referer") 
array2=("another webpage" "another referer") 

for i in "${array[@]}" "${array2[@]}" #line up multiple web pages 
do 
    #use curl to download the page, giving the referer ("-e") 
    curl -O -e "${i[1]}" "${i[0]}" 
done 

如果我只用一个阵列的工作,我可以很容易地做到这一点是这样的:

array=("webpage" "referer") 
REFERER="${array[1]}" 
PAGE="${array[0]}" 
#use curl to download the page, giving the referer ("-e") 
curl -O -e "$REFERER" "$LINK" 

这一次,我有我要处理多个网页一次,我可以”弄清楚如何正确地做到这一点。

如果有另一种方式来处理多个网页,而不必使用数组和for循环,请让我知道。

回答

0

感谢大家的响应。这两个想法都有好处,但我发现Advanced Bash Guide中的一些代码完全符合我想要做的。

我不能说我完全理解它,但通过使用对数组的间接引用,我可以在for循环中使用多个数组。我不确定本地命令是做什么的,但它是关键(我认为它运行一种eval并将字符串分配给变量)。

这样做的好处是我可以将每个网页和引用者分组到他们自己的数组中。然后,我可以通过创建一个新数组并将其添加到for循环来轻松添加一个新网站。另外,如果我需要向curl命令添加更多变量(例如cookie),我可以轻松扩展数组。

function get_page() { 
     OLD_IFS="$IFS" 
     IFS=$'\n'  # If the element has spaces, when using 
         # local to assign variables 

     local ${!1} 


     # Print variable 
     echo First Variable: "\"$a\"" 
     echo Second Variable: "\"$b\"" 
     echo --------------- 
     echo curl -O -e "\"$a\"" "\"$b\"" 
     echo 
     IFS="$OLD_IFS" 
}  

#notice the addition of "a=" and "b=" 
#this is not an associative array, that would be [a]= and [b]= 
array=(a="webpage" b="referer") 
array2=(a="another webpage" b="another referer") 

#This is just a regular string in the for loop, it doesn't mean anything 
#until the indirect referencing later 
for i in "array[*]" "array2[*]" #line up multiple web pages 
do 
     #must use a function so that the local command works 
     #but I'm sure there's a way to do the same thing without using local 
     get_page "$i" 
done 

这导致:

First Variable: "webpage" 
Second Variable: "referer" 
--------------- 
curl -O -e "webpage" "referer" 

First Variable: "another webpage" 
Second Variable: "another referer" 
--------------- 
curl -O -e "another webpage" "another referer" 
5

如果有另一种方式来处理多个网页,而不必使用数组和for循环,请让我知道。

使用数组很好,至少比使用空格分隔的列表或类似的黑客好得多。简单地遍历索引:

array=('webpage' 'another webpage') 
array2=('referrer' 'another referrer') 
# note the different layout! 
for i in "${!array[@]}" 
do 
    webpage="${array[$i]}" 
    referrer="${array2[$i]}" 
done 
0

你需要一个技巧在这里。请注意,空格网址中不允许,所以你可以说:

webpages=("url referrer" "url2 ref2" ...) 

for i in "${webpages[@]}" ; do 
    set -- "$i" 
    url="$1" 
    ref="$2" 

    curl -O -e "${url}" "${ref}" 
done 

[编辑]也许有更好的解决办法,是把所有的URL转换成一个文件,然后使用此代码:

while read url ref ; do 
    curl -O -e "${url}" "${ref}" 
done < file 

或者如果你喜欢here documents

while read url ref ; do 
    echo "url=$url ref=$ref" 
done <<EOF 
url1 ref1 
url2 ref2 
... xxx 
EOF 
+0

Bash可以对空格进行分割,而无需在循环内的每次迭代中对外部程序进行两次调用。 – 2010-07-20 13:08:04

+0

对不起,让你失望,但'expr'是一个bash内建的。 – 2010-07-20 14:20:57

+0

'哪个expr'返回/ usr/bin/expr – Menachem 2010-07-20 15:30:23

0

就像一个普通的旁白:在函数里,至少只是声明IFS变量,其范围仅限制于该功能。无需保存&通过OLD_IFS恢复IFS!

help declare 

IFS=$' \t\n' 
printf "%q\n" "$IFS" 

function ifs_test() { 
    declare IFS 
    IFS=$'\n' 
    printf "%q\n" "$IFS" 
    return 0 
} 

ifs_test 

printf "%q\n" "$IFS" 
相关问题