bash提取字符串段并存储在变量中

cod*_*der 3 linux bash awk

我想将cppclean的输出转换为类似cppcheck的xml部分,例如:

./bit_limits.cpp:25: static data 'bit_limits::max_name_length'

变成:

<error id="static data" msg="bit_limits::max_name_length">
    <location file="./bit_limits.cpp" line="25"/>
</error>
Run Code Online (Sandbox Code Playgroud)

我从awk开始:

测试代码:

echo "./bit_limits.cpp:25: static data 'bit_limits::max_name_length'" > test
cat test.out | awk -F ":" '{print "<error id=\""$3"\""}
                           {print "msg=\""}{for(i=4;i<=NF;++i)print ":"$i}{print "\">"}
                           {print "<location file=\""$1"\" line=\""$2"\"/>"}
                           {print "</error>"}'
Run Code Online (Sandbox Code Playgroud)

注意:要运行此cat命令,您需要将命令放回到一行中-为了便于阅读,我将其打印在多行上。

说明: 我正在使用awk冒号“:”并用冒号定界-将行分成有用的块,然后尝试将其构造成XML:

  • {print "<error id=\""$3"\""} -提取错误ID部分
  • {print "msg=\""}{for(i=4;i<=NF;++i)print ":"$i}{print "\">"} -提取消息(替换缺少的冒号,这就是所有剩余的部分
  • {print "<location file=\""$1"\" line=\""$2"\"/>"} -提取文件和行,这部分很容易,因为冒号排列很好
  • {print "</error>"} -最后打印结束标签

这很接近,但不太正确,它产生:

<error id=" static data 'bit_limits"
msg="
:
:max_name_length'
">
<location file="./bit_limits.cpp" line="25"/>
</error>
Run Code Online (Sandbox Code Playgroud)

ID字段应该仅仅是“静态数据”和味精场应该是“‘bit_limits :: MAX_NAME_LENGTH’”,但其他然后,它是确定(我不介意它是此刻的多线分-尽管我希望awk不会每次都打印新行。

更新 作为@charlesduffy指出-上下文-我想这样做,在bash因为我想以嵌入此代码为最大的可移植性生成文件(或只是一个正常的bash脚本)(即不需要Python或其他工具)。

Cyr*_*rus 5

使用bash和正则表达式:

x="./bit_limits.cpp:25: static data 'bit_limits::max_name_length'"
[[ $x =~ (.+):([0-9]+):\ (.+)\ \'(.+)\' ]]

declare -p BASH_REMATCH
Run Code Online (Sandbox Code Playgroud)

输出:

声明-ar BASH_REMATCH ='([0] =“ ./ bit_limits.cpp:25:静态数据'\''bit_limits :: max_name_length'\''” [1] =“ ./ bit_limits.cpp” [2] = “ 25” [3] =“静态数据” [4] =“ bit_limits :: max_name_length”)'

数组BASH_REMATCH中的元素1到4包含搜索到的字符串。

来自man bash

BASH_REMATCH:一个数组变量,其成员由=~二进制运算符分配给[[条件命令。索引为0的元素是字符串中与整个正则表达式匹配的部分。索引为n的元素是字符串中与第n个带括号的子表达式匹配的部分。该变量是只读的。