这是一个简单的脚本,它可以卷曲https://unix.stackexchange.com/并将结果存储到数组中,效果很好。
#!/usr/local/bin/bash
[ -f pgtoscrap ] && { rm pgtoscrap; };
curl -o pgtoscrap https://unix.stackexchange.com/;
declare -a arr;
fileName="pgtoscrap";
exec 10<&0
exec < $fileName
let count=0
while read LINE; do
arr[$count]=$LINE
((count++))
done
exec 0<10 10<&-
但是,每次我运行此脚本时;错误的文件描述符出现一些错误。
./shcrap
./shcrap: line 14: 10: No such file or directory
我想我不太了解如何exec
正确地在循环中使用命令。有人可以解释吗?
-在实施mapfile
Bash 4之后进行更新,它变得更加简单-
#!/usr/local/bin/bash
## Pass a parameter as e.g. ./linkscrapping.bash https://unix.stackexchange.com/
mapfile -t arr < <(curl -s $1); ## Doing exec stuff with process substitution
regex="<a[[:print:]]*<\/a>"; ELEMENTS=${#arr[@]}; firstline=0;
for((i=0;i<$ELEMENTS;i++)); do
if [[ ${arr[${i}]} =~ $regex ]]; then
[[ $firstline<1 ]] &&
{ echo ${BASH_REMATCH[0]} > scrapped; let firstline=$firstline+1; } ||
{ echo ${BASH_REMATCH[0]} >> scrapped; }
fi
done
pg2scrap="scrapped"; mapfile -t arr2 < <(cat $pg2scrap);
regex="href=[\"\'][0-9a-zA-Z\:\/\.]+"; ELEMENTS2=${#arr2[@]}; line2=0
for ((i=0;i<$ELEMENTS2;i++)); do
if [[ ${arr2[${i}]} =~ $regex ]]; then
[[ $line2<1 ]] &&
{ echo ${BASH_REMATCH[0]#href=\"} > links; (( line2++ )); } ||
{ echo ${BASH_REMATCH[0]#href=\"} >> links; }
fi
done; cat links;
当然,这与您如何关闭先前为stdin打开的文件描述符有关。使用以下应该很好
exec 10<&-
当您这样做时0<10
,您指示外壳程序10
在当前目录中命名的文件的内容中寻找和吸收它,在这种情况下这是没有意义的。
在中,bash
您还可以使用另一种形式exec 10>&-
来达到关闭描述符的相同目的。
但这就是说,您不需要使用exec
随机文件描述符并读取输入,您可以使用以下bash
形式的流程替换技术读取您的输入< <()
:
while IFS= read -r line; do
arr["$count"]="$line"
((count++))
done< <(pgtoscrap)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句