Bash脚本问题:使用select命令如何截取service名称并展示对应info
解决方法
首先修正你原脚本的两个核心问题:
- 数组赋值时未用双引号,导致带空格的行被拆分成多个数组元素
select直接展示整行,未提取service部分
以下是两种可行的实现方案:
方案一:双数组存储(高效匹配)
用两个数组分别存储完整行和对应的service名称,通过索引直接关联,性能更优:
#!/bin/bash file='service.txt' # 存储每行完整内容的数组 full_lines=() # 存储service名称的数组 service_names=() # 读取文件并填充数组 while read -r line; do full_lines+=("$line") # 提取service部分(兼容"-"前后任意数量的空格) service=$(awk -F' *- *' '{print $1}' <<< "$line") service_names+=("$service") done < "$file" echo "Select the service..." # 用service名称作为select选项 select selected_service in "${service_names[@]}"; do # 转换选择序号为数组索引(select的REPLY是用户输入的数字,从1开始) index=$((REPLY - 1)) # 验证索引合法性 if (( index >= 0 && index < ${#full_lines[@]} )); then # 提取对应info内容 info=$(awk -F' *- *' '{print substr($0, index($0, $2))}' <<< "${full_lines[$index]}") echo "Selected service: $selected_service" echo "Corresponding info: $info" break else echo "Invalid selection, please enter a number between 1 and ${#service_names[@]}." continue fi done exit 0
方案二:单数组遍历匹配(无需额外数组)
如果不想维护两个数组,可以在选中service后遍历原数组匹配对应行:
#!/bin/bash file='service.txt' full_lines=() # 读取文件到数组 while read -r line; do full_lines+=("$line") done < "$file" # 生成service选项列表 service_options=() for line in "${full_lines[@]}"; do service_options+=("$(awk -F' *- *' '{print $1}' <<< "$line")") done echo "Select the service..." select selected_service in "${service_options[@]}"; do # 遍历数组找到对应行 for line in "${full_lines[@]}"; do if [[ "$line" == "$selected_service"*" - "* ]]; then # 截取info部分 info="${line#* - }" echo "Selected service: $selected_service" echo "Corresponding info: $info" break 2 # 跳出两层循环 fi done echo "Invalid selection, please try again." done exit 0
关键说明
- 用
awk -F' *- *'替代cut,可以处理-前后任意数量的空格,兼容性更强 - 数组赋值必须用双引号
"$line",避免带空格的内容被错误分词 select的REPLY变量存储用户输入的序号,转换为数组索引时要减1(数组索引从0开始)
内容的提问来源于stack exchange,提问作者Seawolf02
相关产品推荐
相关产品推荐

