我有一个父文件夹(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=(.*?)\\'