仅返回匹配模式之后的行部分 (Unix)

仅返回匹配模式之后的行部分 (Unix)

我有一个父文件夹(abeps),其中包含输出文件所在的几个子文件夹(1,2,3....25),其中一个子文件夹的名称相同(opt.out)。在这个文件中有一个不可预测的输出。这是我需要过滤的行的示例:

A\HF=-1378.9118397\RMSD=4.560e-09\RMSF=1.758e-05\偶极子=0.2110167,0.39

或者

978,3.8529967641,3.6669041122\版本=ES64L-G09RevD.01\状态=1-A\HF=-

所以问题是我有兴趣得到 \HF= 和直到 \ 之间的所有内容

但它们可能位于不同的行,甚至 HF 也可能位于不同的行,所以 grep 不会捕获它。然后我尝试将结果写入文件中:

grep 'HF=-' abeps/*/opt.out > data

结果得到这个

abeps/10/opt.out: 1-A\HF=-1378.9114895\RMSD=5.126e-09\RMSF=5.036

abeps/12/opt.out: \State=1-A\HF=-1378.9185518\RMSD=2.940e-09\RMSF

abeps/13/opt.out: 33413\版本=ES64L-G09RevD.01\状态=1-A\HF=-137

答案1

如果您的 grep 版本支持 PCRE(Perl 兼容正则表达式),您可以使用 Perl 的lookbehind 和lookahead 功能

grep -oPz '(?<=\\HF=)(.|\n)+?(?=\\)'

或与pcregrep(如果有的话)

pcregrep -Mo '(?<=\\HF=)(.|\n)+?(?=\\)'

请记住,如果您感兴趣的模式确实是按行分割的,则返回的文本将保留换行符 - 您可能希望在使用结果时tr或之前将其删除。sed

如果文本本身不能分割成行(只有\HF\标记),那么您可以(.|\n)+?用更简单的.+?ie替换

grep -oPz '(?<=\\HF=).+?(?=\\)'

如果甚至\HF=标记可能在任何点被换行符分割(如您对原始帖子的评论所示),则需要稍微不同的方法,因为 PCRE 目前不支持可变长度后向查找。在这种情况下,你可以尝试

grep -oPz '\\\n?H\n?F\n?=\K(.|\n)+?(?=\\)'

其中lookbehind被伪锚表达式替换,使用\K

答案2

您还可以使用sed

sed -r '/.*HF=([^\]*)\\?.*/s//\1/g' file

例子:

$ echo 'A\HF=-1378.9118397\RMSD=4.560e-09\RMSF=1.758e-05\Dipole=0.2110167,0.39' | sed -r '/.*HF=([^\]*)\\?.*/s//\1/g'
-1378.9118397

$ echo '978,3.8529967641,3.6669041122\Version=ES64L-G09RevD.01\State=1-A\HF=-' | sed -r '/.*HF=([^\]*)\\?.*/s//\1/g'
-

答案3

最近pcregrep

pcregrep -Mo1 '(?s)\\HF=(.*?)\\'

相关内容