使用 grep 查找关键字,然后列出以下字符,直到下一个;特点

Using grep to find keywords, and then list the following characters until the next ; character

我有一长串化学条件,格式如下:

0.2M sodium acetate; 0.3M ammonium thiosulfate;

摩尔浓度可以用多种方式列出:

x.xM, x.x M, x M

其中 x 位数不同。我想做两件事,使用 grep select 那些数字,然后只列出以下字符,直到 ;。因此,如果我在上面的示例中 select 0.2M,我希望能够列出 sodium acetate.

对于 selecting,我尝试了以下方法:

grep '[0-9]*.[0-9]*[[:space:]]*M' file

所以有任意数量的数字和空格,但总是以M结尾。问题是,它还 select 如下:

0.05MRbCl+MgCl2;

我不太清楚为什么要 selected。理想情况下,我希望 0.05M 被 select 编辑,然后列出 RbCl+MgCl2。我怎样才能做到这一点?

(系统为OS X Yosemite)

它匹配,因为:
[0-9]* 匹配 0
. 匹配任何字符(在这种情况下是 .,但您可能想转义它)
[0-9]* 匹配 05
[[:space:]]* 匹配 05M
之间的空字符串 M 匹配 M

至于如何做你想做的事:我认为如果你不希望数字与输出一起打印,这将需要一个回顾断言或打印特定捕获组的能力,这听起来 OS X 的 grep 不支持。不过,您可以使用类似的方法和稍微更强大的工具:

$ cat test.txt 
0.2M sodium acetate; 0.3M ammonium thiosulfate;
0.05MRbCl+MgCl2;
1.23M dihydrogen monoxide;
45 M xenon quadroxide;

$ perl -ne 'while (/([0-9]*\.)?[0-9]+\s*M\s*([^;]+)/g) { print "\n"; }' test.txt 
sodium acetate
ammonium thiosulfate
RbCl+MgCl2
dihydrogen monoxide
xenon quadroxide

写出来,正则表达式是:
([0-9]*\.)? 可选,一些数字和小数点
[0-9]+一位或多位
\s*M\s* 字母 M,周围有间距
([^;]+) 直到下一个分号(您要打印的内容)之前的所有字符

使用 GNU awk 进行多字符 RSgensub()\s:

$ awk -vRS=';\s*' -vm='0.2M' 'm==gensub(/\s*([0-9.]+)\s*M.*/,"\1M","")' file
0.2M sodium acetate

$ awk -vRS=';\s*' -vm='0.05M' 'm==gensub(/\s*([0-9.]+)\s*M.*/,"\1M","")' file
0.05MRbCl+MgCl2