Bash中基于首行字段位置切割含空格的命令输出列
解决带空格字段的命令输出列提取问题
方案一:利用表头位置进行固定宽度切割
这是完全可行的思路——nmcli和MacOS airport -s的输出表头(如BSSID、RSSI、CHANNEL)位置固定,后续每行的对应字段会和表头严格对齐,直接按位置切割即可。
具体操作步骤:
- 先定位表头中目标字段的起始位置
以airport -s的输出为例:
SSID BSSID RSSI CHANNEL HT CC SECURITY (auth/unicast/group) My Home WiFi aa:bb:cc:dd:ee:ff -55 1 Y US WPA2(PSK/AES/AES)
通过index函数获取表头里各字段的起始坐标,比如BSSID的起始位置是index($0, "BSSID"),RSSI是index($0, "RSSI"),以此类推。
- 用
awk的substr函数按位置提取并清理空格
Mac自带的awk即可运行,无需依赖GNU工具:
airport -s | awk 'NR==1 { bssid_pos = index($0, "BSSID"); rssi_pos = index($0, "RSSI"); channel_pos = index($0, "CHANNEL"); next } { # 按位置截取字段,再去除前后空格 bssid = substr($0, bssid_pos, rssi_pos - bssid_pos - 1); rssi = substr($0, rssi_pos, channel_pos - rssi_pos - 1); channel = substr($0, channel_pos); gsub(/^[ \t]+|[ \t]+$/, "", bssid); gsub(/^[ \t]+|[ \t]+$/, "", rssi); gsub(/^[ \t]+|[ \t]+$/, "", channel); print bssid, rssi, channel }'
方案二:直接调用命令的结构化输出功能
很多工具本身支持输出结构化格式,从根源上避免解析空格分隔文本的麻烦:
- nmcli:用
--fields指定需要的字段,搭配--format csv输出逗号分隔的结构化内容,直接用awk按逗号分割提取:
nmcli device wifi list --fields BSSID,RSSI,CHANNEL --format csv | awk -F, '{print $1, $2, $3}'
- Mac airport:可以通过匹配BSSID的十六进制格式(
XX:XX:XX:XX:XX:XX)来精准定位字段,用perl实现更简洁:
airport -s | perl -ne 'if (/(([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})\s+(-?\d+)\s+(\d+)/) { print "$1 $3 $4\n" }'
方案三:用column统一列宽后提取
Mac自带的column -t可以把不规则空格分隔的输出转换成等宽列,之后直接用awk按列号提取即可:
airport -s | column -t | awk '{print $2, $3, $4}'
注意:如果SSID包含连续空格,column -t会将其合并为单个空格,此时SSID会被识别为第一列,后续BSSID、RSSI、CHANNEL依次为第2、3、4列,适合字段无连续空格的场景。
内容的提问来源于stack exchange,提问作者May11
相关产品推荐
相关产品推荐

