WSL2 Bash中用AWK提取YOLOargs内容至数组,保留引号内完整路径
解决WSL2中awk提取带引号路径的问题
最简便的方法:用GNU awk的FPAT特性
WSL里的awk是GNU版本,刚好支持FPAT这个实用特性,能直接定义字段的匹配规则,完美解决引号内内容不拆分的问题:
awk '/YOLOargs/{flag=1; next} flag{ # 定义字段规则:要么是不含空格和引号的普通内容,要么是双引号包裹的完整内容 FPAT = "([^ \"]+)|(\"[^\"]+\")" # 遍历所有字段,可直接存入数组或做后续处理 for(i=1; i<=NF; i++){ # 如需去掉路径两端的双引号,就保留这行 gsub(/^"|"$/, "", $i) # 示例直接打印元素,实际可将$i赋值给数组 print "第"i"个元素:" $i arr[i] = $i } # 若只需处理YOLOargs下方第一行,保留flag=0;多行则删除该行 flag=0 }' argstext
原理说明
FPAT直接告诉awk如何识别完整字段:要么是没有空格和双引号的普通参数,要么是被双引号包裹的整个路径——不管路径里有多少空格,都会被当成一个独立字段。
兼容老版本awk的方法:手动实现状态机
如果你的awk版本不支持FPAT(WSL环境基本不会遇到),可以自己逐字符扫描文本,跟踪是否处于引号内来拆分元素:
awk '/YOLOargs/{flag=1; next} flag{ line = $0 len = length(line) in_quote = 0 current_elem = "" arr_index = 1 for(i=1; i<=len; i++){ char = substr(line, i, 1) # 碰到引号就切换"是否在引号内"的状态 if(char == "\""){ in_quote = !in_quote # 不想保留引号的话,取消注释下面这行 # continue } # 碰到空格且不在引号内时,将当前累积内容存为一个元素 if(char == " " && !in_quote){ if(current_elem != ""){ arr[arr_index++] = current_elem current_elem = "" } } else { current_elem = current_elem char } } # 处理行尾最后一个元素 if(current_elem != "") arr[arr_index++] = current_elem # 遍历数组打印示例 for(j=1; j<arr_index; j++){ print "第"j"个元素:" arr[j] } flag=0 }' argstext
测试示例
假设你的argstext内容如下:
YOLOargs --weights best.pt --source "/mnt/c/Users/Name/Documents/My Images/test.jpg" --conf 0.5 --name "run output"
运行第一个命令后,输出结果为:
第1个元素:--weights
第2个元素:best.pt
第3个元素:--source
第4个元素:/mnt/c/Users/Name/Documents/My Images/test.jpg
第5个元素:--conf
第6个元素:0.5
第7个元素:--name
第8个元素:run output
带空格的路径会被完整提取为单个元素,不会被拆分。
内容的提问来源于stack exchange,提问作者Jared
相关产品推荐
相关产品推荐

