Regex 搜索与字符串1匹配且未被字符串2分隔的多行文字

Regex 搜索与字符串1匹配且未被字符串2分隔的多行文字,regex,awk,sed,grep,Regex,Awk,Sed,Grep,我有一个这样的文件: abc|100|test|line|with|multiple|information|||in|different||fields abc|100|another|test|line|with|multiple|information|in||different|fields| abc|110|different|looking|line|with|some|supplementary|information abc|100|test|line|with|multiple

我有一个这样的文件:

abc|100|test|line|with|multiple|information|||in|different||fields
abc|100|another|test|line|with|multiple|information|in||different|fields|
abc|110|different|looking|line|with|some|supplementary|information
abc|100|test|line|with|multiple|information|||in|different||fields
abc|110|different|looking|line|with|some|other|supplementary|information
abc|110|different|looking|line|with|additional||information
abc|100|another|test|line|with|multiple|information|in||different|fields|
abc|110|different|looking|line|with|supplementary|information
我正在寻找一个与sed/awk/(e)grep一起使用的regexp(实际上对我来说,哪一个都可以)在上面提到的文本中找到以下内容:

abc|100|test|line|with|multiple|information|||in|different||fields
abc|110|different|looking|line|with|some|other|supplementary|information
abc|110|different|looking|line|with|additional||information
如果在另一行出现之前,后面至少有两行110行,我想返回一行100行。结果应包含初始的| 100 |行以及后面的所有| 110 |行,但不包括下面的| 100 |行

sed -ne '/|100|/,/|110|/p'
为我提供所有| 100 |行的列表,后面至少有一行| 110 |行。但是如果| 110 |行重复了不止一次,它不会检查。我得到了我不期待的结果

sed -ne '/|100|/,/|100|/p'
返回所有| 100 |行以及下一| 100 |行(包括下一| 100 |行)之间的内容的列表

sed -ne '/|100|/,/|110|/p'
试图找出搜索模式之间的界限对我来说总是一场噩梦。我在类似的问题上花了几个小时的反复尝试,终于奏效了。但我一直不明白为什么。我希望,s.o.这次能帮我省去头痛,也许能解释一下这种模式是如何起作用的。我很确定,我会再次面对这种问题,然后我终于可以自己解决了

谢谢你在这方面的帮助

问候


Manuel

在AWK中,字段分隔符设置为管道字符,第二个字段与每行100和110进行比较$0表示输入文件中的一行

BEGIN { FS = "|" }
{
    if($2 == 100) { 
        one_hundred = 1; 
        one_hundred_one = 0;
        var0 = $0
    } 

    if($2 == 110) { 
        one_hundred_one += 1; 
        if(one_hundred_one == 1 && one_hundred = 1) var1 = $0; 
        if(one_hundred_one == 2 && one_hundred = 1) var2 = $0;
    } 

    if(one_hundred == 1 && one_hundred_one == 2) {
        print var0
        print var1
        print var2
    }  
}
awk-f foo.awk input.txt

abc|100|test|line|with|multiple|information|||in|different||fields
abc|110|different|looking|line|with|some|other|supplementary|information
abc|110|different|looking|line|with|additional||information

这里有一个GNU awk特定的答案:使用
|100 |
作为记录分隔符,
|110 |
作为字段分隔符,并查找至少包含3个字段的记录

gawk '
    BEGIN {
        # a newline, the first pipe-delimited column, then the "100" value
        RS="(\n[^|]+[|]100[|])"
        FS="[|]110[|]"
    } 
    NF >= 3 {print RT $0}        # RT is the actual text matching the RS pattern
' file
我会在awk里做这件事

awk -F'|' '$2==100&&c>2{print b} $2==100{c=1;b=$0;next} $2==110&&c{c++;b=b RS $0;next} {c=0}' file
分门别类,便于阅读:

awk -F'|' '

  # If we're starting a new section and conditions have been met, print buffer
  $2==100 && c>2 {print b}

  # Start a section with a new count and a new buffer...
  $2==100 {c=1;b=$0;next}

  # Add to buffer
  $2==110 && c {c++;b=b RS $0}

  # Finally, zero everything if we encounter lines that don't fit the pattern
  {c=0;b=""}

' file
这不是使用正则表达式,而是使用指定的字段分隔符逐步遍历文件。看到“启动”条件后,它开始保留缓冲区。随着后续行与“continue”条件匹配,缓冲区将增长。一旦我们看到一个新部分的开始,如果计数器足够大,我们就打印缓冲区


您的示例数据对我有用。

欢迎使用StackOverflow。Stackoverflow不是免费的代码编写服务。如果你试图写一些东西,但遇到了一些困难,那么展示一下你所做的,并提出一个具体的问题。有关提示,请参阅。如果你只是想做免费的工作,那么StackOverflow就不适合这样的要求。至少尝试使用互联网提供的丰富文档。或者花钱请人替你写。我想,介绍一下我在这方面的基本知识是没有用的。已编辑问题。感谢添加您的尝试。至少它是某种东西。:)关闭投票被撤回。你希望
$2==100
避免匹配“41004”@glennjackman yea这样的值。从问题中我不太确定他是想要一个正则表达式匹配还是一个文本值,按照你的建议更新了我的回复,我想他最终必须决定他想要什么。搜索的值正好是100-字段中的信息限制在100到900之间的数字值。我已经检查过了,这个解决方案也有效。谢谢你的帮助!很乐意帮忙!我想到的一个附带条件是,如果文件末尾存在行模式(100后跟2个或更多110),则不会打印,因为只有当脚本看到
$2==100
时才会打印。如果需要,可以使用包含
if()
END
部分来解决此问题。