在bash中检索属性的值

时间:2015-04-16 09:42:07

标签: regex bash

我有一个行列表:

 <some_random_text="someval" my_val_="0.4" some_random_text_1="someval_">
 <some_random_text="someval" my_val_="0.8" some_random_text_1="someval_">
 <some_random_text="someval" my_val_="1.2" some_random_text_1="someval_">

等等。

从每一行开始,我想返回my_val_之后给出的数值。我怎么能用bash做到这一点?

2 个答案:

答案 0 :(得分:7)

使用grep

grep -oP 'my_val_="\K[^"]*' filename

-o以便grep仅打印匹配-P,以便使用与Perl兼容的正则表达式。

正则表达式中的\K从匹配中删除了前面的正则表达式部分匹配的所有内容;这具有lookbehind的效果:只有在my_val_="之后直接匹配的非引号字符才会匹配。

答案 1 :(得分:7)

在这个非常严格的结构中,你想要做的就是使用sed非常容易:

sed 's/.*my_val_="\([0-9.]\{1,\}\)".*/\1/' file

或使用扩展正则表达式:

sed -r 's/.*my_val_="([0-9.]+)".*/\1/' file

这会捕获您感兴趣的部分(引号之间的数字和点),并使用它们来替换该行的内容。

正如评论中所提到的(感谢),启用扩展正则表达式的开关在sed版本之间有所不同。出于习惯,我倾向于使用-r但是一些实现(例如OSX上的BSD sed)与-E一起使用。其他人使用-r-Eneither option is defined by the standard

这个也可以在原生bash中完成(虽然我不推荐它......):

re='my_val_="([0-9.]+)"'
while read -r line; do
    [[ $line =~ $re ]] && echo "${BASH_REMATCH[1]}"
done < file

=~是正则表达式匹配运算符。捕获的数字和点存储在特殊数组1的元素BASH_REMATCH中。


sed和bash方法略有不同,因为sed版本将打印文件中的所有行,即使它们与模式不匹配。如果这是一个问题,您可以在命令末尾添加-n开关和p来打印匹配的行:

sed -nr 's/.*my_val_="([0-9.]+)".*/\1/p' file