使用bash在模式之间创建Grep文本

使用bash在模式之间创建Grep文本,bash,awk,sed,grep,Bash,Awk,Sed,Grep,我需要对txt文件中的数据进行排序。样本数据如下: ====== Jhon Doe score - ------ ====== Ann Smith score + ------ ====== Will Marrow score - ------ sed -n '/^======/{:a;N;/\n------/!ba;/score +/p}' infile ====== Ann Smith score + ------ 我只需要提取定义了score+的部分。所以结

我需要对txt文件中的数据进行排序。样本数据如下:

======
Jhon 
Doe 
score -
------  
======
Ann 
Smith 
score + 
------
======
Will 
Marrow 
score - 
------
sed -n '/^======/{:a;N;/\n------/!ba;/score +/p}' infile 
======
Ann 
Smith 
score + 
------
我只需要提取定义了score+的部分。所以结果应该是

======
Ann 
Smith 
score + 
------

尝试一下这款oneliner:

awk -v RS="==*" -F'\n' '{p=0;for(i=1;i<=NF;i++)if($i~/score \+/)p=1}p' file
其思想是,将所有行除以==。。。作为一条多行记录,并检查该记录是否包含搜索模式,将其打印出来。

给定:

$ echo "$txt"
======
Jhon 
Doe 
score -
------  
======
Ann 
Smith 
score + 
------
======
Will 
Marrow 
score - 
------
您可以在awk中创建切换类型匹配,以便仅打印您要打印的部分:

$ echo "$txt" | awk '/^=+/{f=1;s=$0;next} /^score \+/{f=2} f {s=s"\n"$0} /^-+$/ {if(f==2) {print s} f=0}'
======
Ann 
Smith 
score + 
------
我想试试这个:

$ grep -B3 -A1 "score +" myfile

这意味着。。。grep分数+前三行,分数+后一行。

Sed可以按如下方式执行:

======
Jhon 
Doe 
score -
------  
======
Ann 
Smith 
score + 
------
======
Will 
Marrow 
score - 
------
sed -n '/^======/{:a;N;/\n------/!ba;/score +/p}' infile 
======
Ann 
Smith 
score + 
------
其中-n阻止打印,以及

/^======/ {       # If the pattern space starts with "======"
    :a            # Label to branch to
    N             # Append next line to pattern space
    /\n------/!ba # If we don't match "------", branch to :a
    /score +/p    # If we match "score +", print the pattern space
}

可以用/\n----$/更准确地定位事物,但行的末尾有空格,我不确定这些是真实的还是复制粘贴的人工制品,但这对示例数据有效。

对于多字符的GNU awk:

$ awk -v RS='=+\n' '/score \+/' file
Ann 
Smith 
score + 
------
使用Grep上下文标志 假设您有一个真正固定格式的文件,您可以只使用fgrep、GNU或BSD grep以及speedy-fixed strings标志以及-before context和-after context标志。例如:

$ fgrep -A1 -B3 'score +' /tmp/foo 
======
Ann 
Smith 
score + 
------

这些标志将找到您的匹配项,并包括每个匹配项之前的三行和之后的一行。这将为您提供所需的输出,但比sed或awk脚本复杂得多。YMMV.

也许编写perl脚本是更好的选择,如果它解决了这个任务,grep只处理行。你想多线比赛真棒,工作如期!如果定义了更多的模式,您还可以演示如何提取数据吗。例如,不仅仅是分数+而且还有一个,例如:年龄-所以两种模式应该只在===和---@Demontager之间如果你想检查A和B,只需在if..Tested中写入逻辑,也可以工作!更优雅的方式,我理解它的逻辑。如果我想要===和之间的两个匹配模式-例如添加了年龄-?@Demontager是年龄-总是在分数+?之间的任何地方===和-,你必须用/score+/{/age-/p}替换分数线。我做错了$sed-n'/^====/{:a;n;/--/!ba;/score+/{/age-/p}'test1.txt sed:-e表达式1,char 0:unmatched`{'你能不能显示完整的行。是的,非常小的方式。但如果每个部分的行数相等,则按预期提取数据。对于我的示例,它非常适合。