优化iOS模拟器筛选方案:改进bash实现及sed/awk替代方案
iOS模拟器筛选:提取Booted状态设备的优化方案与实现
问题描述
我有xcrun simctl list devices命令的输出文件simulators.txt,目标是筛选出状态为Booted的iOS模拟器,输出需保留设备型号、iOS版本和UUID。目前已尝试sed(输出不符合预期)和bash函数(已得到目标格式),现咨询:
- 如何优化该bash方案,有无更高效简洁的最佳实践?
- 如何仅用sed或awk实现相同的筛选输出效果?
一、Bash方案的优化与最佳实践
纯Bash内置实现(低开销)
如果追求最小化外部工具调用,直接用Bash原生语法处理,避免频繁创建子进程:
#!/bin/bash current_ios="" while IFS= read -r line; do # 捕获iOS版本行(格式:-- iOS 16.4 --) if [[ $line =~ ^--[[:space:]]+iOS[[:space:]]+([0-9.]+)[[:space:]]+--$ ]]; then current_ios="${BASH_REMATCH[1]}" # 捕获Booted状态的设备行 elif [[ $line =~ ^[[:space:]]*(.*)[[:space:]]+\(([^)]+)\)[[:space:]]+\(Booted\)$ ]]; then echo "型号: ${BASH_REMATCH[1]}, iOS版本: $current_ios, UUID: ${BASH_REMATCH[2]}" fi done < simulators.txt
优化点:
- 用Bash原生正则
=~替代外部工具,减少进程开销 - 逐行读取时缓存当前iOS版本,避免重复解析
- 仅处理关键行,跳过无效内容
简洁的Bash+Awk组合(兼顾效率与可读性)
如果不需要纯Bash实现,结合Awk可以大幅简化代码,同时保持高效:
awk '/^-- iOS/ {ios_version = $3} /Booted/ {match($0,/^[[:space:]]*(.*)[[:space:]]+\(([^)]+)\)/,arr); print "型号: "arr[1]", iOS版本: "ios_version", UUID: "arr[2]}' simulators.txt
一行完成筛选、提取、输出,比纯Bash更简洁,性能也更优。
二、用Sed或Awk单独实现
1. Awk实现(推荐,逻辑清晰易维护)
Awk对结构化文本的处理天生友好,完美适配xcrun simctl的输出格式:
# 一行式执行 awk '/^-- iOS/ {ios_version = $3} /Booted/ {match($0, /^[[:space:]]*(.*)[[:space:]]+\(([^)]+)\)/, arr); printf "型号: %s, iOS版本: %s, UUID: %s\n", arr[1], ios_version, arr[2]}' simulators.txt
逻辑说明:
- 先匹配
-- iOS X.X --格式的行,提取版本号存到变量 - 再匹配包含
Booted的设备行,用正则捕获型号和UUID - 最后组合变量输出目标内容
2. Sed实现(纯正则,适合轻量场景)
注意:macOS默认是BSD Sed,和GNU Sed语法略有差异,以下分别提供两种版本:
GNU Sed(Linux/WSL)
sed -n '/^-- iOS/{s/^.*iOS //;s/ --$//;h};/Booted/{G;s/^[[:space:]]*\(.*\)[[:space:]](\([^)]*\))[[:space:]]\(Booted\)\n\(.*\)/型号: \1, iOS版本: \4, UUID: \2/;p}' simulators.txt
BSD Sed(macOS)
sed -n -e '/^-- iOS/{s/^.*iOS //;s/ --$//;h}' -e '/Booted/{G;s/^[[:space:]]*\(.*\)[[:space:]](\([^)]*\))[[:space:]]\(Booted\)\ \(.*\)/型号: \1, iOS版本: \4, UUID: \2/;p}' simulators.txt
逻辑说明:
- 先捕获iOS版本行,清理后存入临时缓存区
- 处理Booted设备行时,把缓存的版本号追加到当前行
- 用正则替换提取所有目标字段并输出
内容的提问来源于stack exchange,提问作者EdYuTo
相关产品推荐
相关产品推荐

