我写了一个小 bash 脚本,sed
在一些 html 页面上使用它来提取一些 url。
为了避免每次抓取变量中的 sed 结果然后再次读取它,我简单地创建了 3 个函数并通过管道连接在一起。
first_function $1 | second_function | third_function
这么说吧:
- 第一个函数从给定的列表中查找项目 url链接地址(
$1
) - 第二个函数从每个管道 URL 中提取图像
src
- 第三个函数组装输出 HTML
现在我回显$lot_url
,second_function
所以我可以read
将它third_function
一起$img_url
放入 HTML 中。
会更干净如果我可以将它作为一个可以访问的全局变量 second_function
但third_function
似乎我不能。
随着函数之间传递的值数量的增加,这一点变得更加必要。
这里是完整的示例代码:
first_function(){
curl -s "$1" | sed -nr '
#extract sub urls
'
}
second_function(){
while read lot_url; do
echo "$lot_url"
curl -s "$lot_url" | sed -nr '
#extract img src
'
done
}
third_function(){
while read lot_url; read img_url; do
echo "<a href="$lot_url"><img src="$img_url" /></a>"
done
}
first_function "$1" | second_function | third_function
答案1
管道的两侧处于不同的过程中。您不能在这些进程之间共享变量。如果您想共享数据,您要么必须通过管道传递数据,要么使用备用通信通道。如果您需要备用通信渠道,则您超出了 shell 的功能,请切换到真正的编程语言。
在这里,在第二个管道中并行lot_url
对img_url
我来说似乎是一个很好的解决方案。我会在同一条线上传递它们。假设您的 URL 已正确转义,则不需要任何特定的引用,您可以在同一行上传递它们。这样做的优点是允许img_url
每个 中的 s数量可变lot_url
。
second_function(){
while read lot_url; do
echo "$lot_url"
curl -s "$lot_url" | sed -nr -e '
#extract img src
' -e "s>^>$lot_url >"
done
}
third_function(){
while read lot_url img_url; do
echo "<a href="$lot_url"><img src="$img_url" /></a>"
done
}
答案2
我认为一个 while 循环在这里就可以了。我认为这实际上没有什么区别,因为无论如何你每次迭代都会调用可执行文件。这样你能共享您所希望的全局变量。喜欢:
source_cmd |
while read var
do fn1 "$var" |
fn2 "$var"
done
但我认为最好还是稍微改变一下工作流程 - 该函数只不过是一组基于数组的 shell 命令。现在您没有将数组用于其中任何一个,因此它确实应该用于指出一组命令的共同目的 - 我能看到的最常见的似乎是curl ... | sed ...
.所以我建议你应该让它成为一个可以接受参数的函数。所以结果可能是这样的:
curl_sed() { url=$1 && shift
curl -s "$url" | sed -nr "$*"
}
fn() { URL=$1 && shift
set -- '#extract sub url sed script' \
'#extract img src sed script'
curl_sed "$URL" "$1" |
while read lot_url
do IFS='
'; printf '<a href="'"$lot_url"'"><img src="%s" /></a>\n' \
$(curl_sed "$lot_url" "$2")
done
}
你已经接受了吉尔斯对这个问题的回答——显然是几年前,我没有意识到——但是这是另一个这展示了与我的方法类似的方法,并且我认为它更适合此目的。