是否可以使用bash访问for循环中的多个数组

时间:2010-07-20 08:32:26

标签: arrays bash for-loop

我正在尝试编写一个bash脚本,让我可以使用curl下载多个网页。对于每个网页,我希望能够传递curl页面和referer链接。我希望能够一次提供多个网页。

换句话说,我希望能够遍历我提供脚本的网页,并且对于每个页面,将关联的网页和引用链接传递给curl。

我以为我会使用数组将网页和引用链接存储在一个变量中,以为我可以在运行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循环,请告诉我。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

你需要一个技巧。请注意,URL中不允许使用空格,因此您可以说:

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

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

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

[编辑]也许更好的解决方案是将所有网址放入文件中,然后使用此代码:

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

答案 2 :(得分: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"

答案 3 :(得分:0)

就像一般情况一样:在函数内部至少只声明IFS变量,将其范围仅限于该函数。无需保存&amp;通过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"