如何将Bash命令输出存入数组且避免重复执行命令
解决Bash中一次性提取findId输出到数组的问题
要避免两次执行findId命令,同时提取id和程序名到数组,我们可以通过一次命令调用获取输出,再用Bash内置工具或awk来解析内容,以下是几种可行的方案:
方案1:用awk快速提取(适合程序名无空格的情况)
如果你的程序名不包含空格,这个方法最简单直接:
# 一次执行findId,提取id和最后一个字段(程序名)到数组 read -r -a result_array <<< "$(findId PATTERN | awk '{print $1, $NF}')" # 验证结果 echo "ID: ${result_array[0]}" echo "程序名: ${result_array[1]}"
原理
awk '{print $1, $NF}':$1取输出的第一个字段(id),$NF取最后一个字段(程序名),把这两个值用空格分隔输出。read -r -a result_array:把awk输出的两个值读入数组result_array,-r避免转义字符被处理,-a表示读入数组。
方案2:处理带引号的错误信息和含空格的程序名
如果errorcode是带引号的多字符串,或者程序名可能包含空格,需要更精准的解析:
# 一次执行命令并保存输出 full_output=$(findId PATTERN) # 提取id:截取第一个空格前的内容 id="${full_output%% *}" # 定位第二个双引号的位置 first_quote=$(expr index "$full_output" "\"") second_quote=$(expr index "${full_output:$first_quote+1}" "\"") + $first_quote # 提取程序名:从第二个双引号后截取,并去掉开头的空格 program_name="${full_output:$second_quote+1}" program_name="${program_name# }" # 存入数组 result_array=("$id" "$program_name") # 验证 echo "ID: ${result_array[0]}" echo "程序名: ${result_array[1]}"
原理
${full_output%% *}:Bash参数扩展,从字符串末尾删除最长的*(任意字符+空格),得到第一个空格前的id。expr index:定位双引号的位置,确保我们跳过中间带引号的errorcode部分,直接提取后面的程序名。
方案3:处理多行输出的情况
如果findId返回多行结果,需要把所有id和程序名分别存入数组:
# 初始化两个数组,分别存储id和程序名 declare -a id_list program_list # 一次性执行findId,逐行处理输出 while IFS= read -r line; do # 提取当前行的id current_id="${line%% *}" # 定位第二个双引号 f_quote=$(expr index "$line" "\"") s_quote=$(expr index "${line:$f_quote+1}" "\"") + $f_quote # 提取当前行的程序名 current_program="${line:$s_quote+1}" current_program="${current_program# }" # 添加到数组 id_list+=("$current_id") program_list+=("$current_program") done < <(findId PATTERN) # 验证结果 echo "第一行ID: ${id_list[0]}" echo "第一行程序名: ${program_list[0]}" echo "第二行ID: ${id_list[1]}" echo "第二行程序名: ${program_list[1]}"
原理
< <(findId PATTERN):进程替换,把findId的输出作为while循环的输入,只执行一次命令。IFS= read -r line:确保读取整行,包括开头的空格,-r避免转义字符被解析。
所有方案都只执行一次findId命令,完全避免了两次执行结果不一致的问题。
内容的提问来源于stack exchange,提问作者demien
相关产品推荐
相关产品推荐

