如何将grep提取的Azure DevOps构建号存入数组并实现逐个访问与循环
如何将grep提取的Azure DevOps构建号存入数组并实现逐个访问与循环
我完全懂你的困扰——你已经成功从URL里抠出了构建号,但就是没法把它们当成独立的条目来用,每次访问索引得到的都是单个字符,循环也没法正常工作,对吧?咱们一步步把这个问题解决掉。
为什么你之前的方法不行?
你用queued_builds="$(grep ...)"这种方式赋值时,bash会把命令的所有输出(包括换行符)当成一个单一的字符串,而不是数组。当你尝试echo $queued_builds[1]时,bash其实会把它解析成$queued_builds(整个长字符串)加上[1],而因为这不是真正的数组,它会默认取字符串的第一个字符,这就是为什么你看到的是2而不是238。
正确的数组赋值方法
这里有两种靠谱的方式,把每个构建号变成数组的独立元素:
方法1:用mapfile(推荐,bash 4.0+支持)
这是最简洁的写法,mapfile会自动把输入的每一行作为数组的一个元素,-t参数还会帮你去掉每行末尾的换行符:
mapfile -t queued_builds < <(grep _apis/build/Builds build.txt | cut -d "/" -f9 | grep -Eo '[0-9]*')
这里的< <(command)是进程替换,把后面命令的输出当成mapfile的输入源。
方法2:循环读取(兼容旧版bash)
如果你的bash版本比较旧,不支持mapfile,可以先初始化一个空数组,再循环读取每一行添加进去:
# 先创建一个空数组 queued_builds=() # 循环读取命令输出的每一行,添加到数组 while IFS= read -r line; do queued_builds+=("$line") done < <(grep _apis/build/Builds build.txt | cut -d "/" -f9 | grep -Eo '[0-9]*')
IFS=和-r是为了避免读取时出现意外的字符截断,哪怕你的构建号没有特殊字符,养成这个习惯也没坏处。
验证数组是否正确
现在你可以正常访问数组元素了:
- 打印整个数组:
echo "${queued_builds[@]}"(每个元素会分开显示) - 访问单个元素:注意bash数组是从0开始索引的!比如
echo "${queued_builds[0]}"会输出238,echo "${queued_builds[1]}"输出239,以此类推。
你的循环怎么改?
现在数组是正确的,你的循环只需要稍微调整下(加双引号更安全,避免特殊字符问题):
# 替换成你的组织和项目名 organization="example" project="5121186b-6db9-49f7-8fcd-64e88a5c606d" for build in "${queued_builds[@]}"; do echo "https://dev.azure.com/${organization}/${project}/_apis/build/builds/$build?api-version=7.0" done
额外优化:简化提取命令
其实你可以用awk一步到位提取构建号,省掉多次grep和cut的管道:
mapfile -t queued_builds < <(awk '/_apis\/build\/Builds/ {match($2, /[0-9]+$/); print substr($2, RSTART, RLENGTH)}' build.txt)
这个命令会直接匹配包含目标路径的行,然后提取URL末尾的数字序列,一步得到你要的构建号。
备注:内容来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

