如何定位文本中偶数个双引号后的首个#索引?脚本结果异常
解决双引号外第一个#的索引定位问题
需求说明
需要从每行文本中,找到**位于偶数个双引号之后的第一个#**的索引(索引从0开始),也就是不在双引号包裹范围内的第一个#的位置。
测试文本文件内容
e2c=["(vsim-86)" ,'kkk', "pppp", "bbbbbb", #"old", "uio", " sds # sds", #"old2", " sds # sds", " a # b",#"old2", # ' sds # sds', # - "example of string to override" "aaaaaa" ]
现有脚本问题
现有bash脚本通过grep -P配合awk的方式,错误匹配了双引号内的#:
- 对于行
" sds # sds", #"old2",,返回索引6(对应双引号内的#),预期应为14(双引号外的第一个#) - 对于行
" sds # sds", " a # b",#"old2",,返回索引6,预期应为23
现有脚本代码:
while IFS= read -r rline; do echo $rline # prints a line from the file index=$(grep -P '(^[^"]*(["][^"]*["][^"]*){0,}[^"]*#)' <<< "$rline" | awk '{print index($0, "#")-1}') echo "The index of the first not in string # is: $index" done < file.txt
修正方案
直接用awk跟踪双引号状态,精准定位目标#:
while IFS= read -r rline; do echo "$rline" index=$(awk -v line="$rline" ' BEGIN { in_quote = 0 len = length(line) for (i=1; i<=len; i++) { char = substr(line, i, 1) if (char == "\"") { in_quote = !in_quote } else if (char == "#" && in_quote == 0) { print i-1 exit } } print "" }') echo "The index of the first not in string # is: $index" done < file.txt
逻辑说明
- 遍历每行的每个字符,维护
in_quote变量标记当前是否处于双引号内(遇到"就翻转状态) - 当遇到
#且in_quote为0(不在双引号内)时,输出当前索引(减1转为0起始)并退出循环 - 若遍历完未找到符合条件的
#,输出空字符串
正确输出结果
e2c=["(vsim-86)" ,'kkk', "pppp", The index of the first not in string # is: "bbbbbb", #"old", "uio", The index of the first not in string # is: 10 " sds # sds", #"old2", The index of the first not in string # is: 14 " sds # sds", " a # b",#"old2", The index of the first not in string # is: 23 # ' sds # sds', The index of the first not in string # is: 0 # - "example of string to override" The index of the first not in string # is: 0 "aaaaaa" ] The index of the first not in string # is:
内容的提问来源于stack exchange,提问作者taquionbcn
相关产品推荐
相关产品推荐

