我的文件看起来像这样:
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一起使用的正则表达式(它对我来说实际上对我来说无关紧要)在上面找到以下内容提到的文字:
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
我想找回| 100 |如果后面跟着至少两个| 110 |在另一个之前的行| 100 |出现了一行。结果应该包含初始| 100 |与所有| 110 |一起排队后面的行但不是以下的| 100 |线。
sed -ne '/|100|/,/|110|/p'
为我提供了所有| 100 |的列表后面跟着至少一个| 110 |的行线。但它不检查,如果| 110 |线已多次重复。我得到了我不想找的结果。
sed -ne '/|100|/,/|100|/p'
返回所有| 100 |的列表行和下一个| 100 |之间的内容行包括下一个| 100 |线。
试图在搜索模式之间找到线条对我来说总是一场噩梦。我花了几个小时的尝试和错误来解决最终有效的类似问题。但我从来没有真正理解为什么。希望如此。这次可能会让我很头疼,也许可以解释这种模式是如何起作用的。我很确定,我会再次遇到这种问题,然后我终于可以帮助自己。
感谢您对此提供任何帮助!
此致
曼努埃尔
答案 0 :(得分:0)
在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
答案 1 :(得分:0)
这是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
答案 2 :(得分:0)
我会在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
不是使用正则表达式,而是使用您指定的字段分隔符逐步执行该文件。在看到“开始”状态后,它开始保持缓冲区。随后的行与“继续”条件匹配,缓冲区会增长。一旦我们看到新部分的开始,如果计数器足够大,我们就打印缓冲区。
根据您的样本数据为我工作。