在bash中检索属性的值

Vis*_*hal 1 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_">
Run Code Online (Sandbox Code Playgroud)

等等.

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

Win*_*ute 7

grep:

grep -oP 'my_val_="\K[^"]*' filename
Run Code Online (Sandbox Code Playgroud)

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

\K从这场比赛的一切,是由它之前的正则表达式的部分匹配的正则表达式中删除; 这有一个lookbehind的效果:只有my_val_="匹配后直接来的非引号字符.


Tom*_*ech 7

在这个非常严格的结构中,使用sed你想要做的事情很简单:

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

或使用扩展正则表达式:

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

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

正如评论中所提到的(感谢),启用扩展正则表达式的开关在sed版本之间有所不同.出于习惯,我倾向于使用-r但是一些实现(例如OSX上的BSD sed)可以使用-E.其他与任何工作-r-E既不选项由标准定义.

可能也可以在本地的bash做(虽然我不会推荐它...):

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

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


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

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