搜索一个字符串并打印某个范围内前后的所有内容

搜索一个字符串并打印某个范围内前后的所有内容

我有这个文件:

sometext1{
string1
}

sometext2{
string2
string3
}

sometext3{
string4
string5
string6
}

我想在这个文件中搜索特定的字符串,并打印该字符串之前到开头的所有内容{以及该字符串之后到结尾的所有内容}。我尝试使用 sed 来实现此目的,但如果我尝试打印范围内的所有内容,/{/,/string2/例如 sed 会打印以下内容:

sometext1{
string1
}

sometext2{
string2
sometext3{
string4
string5
string6
}

如果我搜索字符串“string2”,我需要输出为:

sometext2{
string2
string3
}

谢谢。

答案1

这里有两个命令。如果你想要一个命令来修剪到.*{$序列中的最后一行(正如 @don_crissti 所做的那样ed你可以做:

sed 'H;/{$/h;/^}/x;/{\n.*PATTERN/!d'

...其工作原理是将每一行附加到ewline 字符H后面的旧空间\n,覆盖h匹配的每一行的旧空间{$,并为匹配的每一行交换hold 和模式空间^}- 从而刷新其缓冲区。

它只打印与{then \newline 和 thenPATTERN在某个点匹配的行 - 并且这只在缓冲区交换后立即发生。

它会删除一系列{$匹配中的任何行,直到序列中的最后一个,但您可以获得所有包含的行,例如:

sed '/PATTERN.*\n/p;//g;/{$/,/^}/H;//x;D'

它的作用是交换h每个序列的模式和旧空格...{$.*^}.*,将序列中的所有行附加到旧行字符H后面的旧空格\n,并在每个行循环中D删除\n模式空间中第一个出现的 ewline 字符,然后再从剩余的内容开始。

当然,它\n在模式空间中获得 ewline 的唯一一次是当输入行匹配时^}(范围的末尾),因此当它在任何其他情况下重新运行脚本时,它只会像往常一样拉入下一个输入行。

但是,当PATTERN在与 ewline 相同的模式空间中找到时,它会在再次\n覆盖它之前打印该批次^}(这样它可以结束范围并刷新缓冲区)

给定这个输入文件(谢谢唐):

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}
}

第一个打印:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

...还有第二个...

sometext2{
PATTERN
string3
}
Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

答案2

这是一个解决方案ed

ed -s filename <<< $'g/PATTERN/?{?,/}/p\nq\n'

那是:

g/PATTERN/     # mark each line matching PATTERN  
?{?,/}/p       # for each marked line, print all lines from the previous { up to the next }  
q              # quit editor

PATTERN这假设每对之间只有一行,否则同一块内{ }的每个附加行都会得到重复的输出。 它将适用于包含单行匹配的多个文件,例如包含两个不同部分的测试文件:PATTERN
{ }PATTERNPATTERN

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN again

another string here
}
}

跑步

ed -s sample <<< $'g/PATTERN/?{?,/}/p\nq\n'

输出:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN again

another string here
}

答案3

pcregrep

pcregrep -M '(?s)\{[^}]*PATTERN.*?\}'

或者使用 GNU grep,前提是输入不包含 NUL 字节:

grep -Poz '.*(?s)\{[^}]*PATTERN.*?\}'

答案4

$ awk 'BEGIN{RS="\n\n"; FS="[{}]"} {if ($2 ~ /string4/) {print $2}}' t1.txt
string4
string5
string6

在哪里:

  • string4--> 需要匹配的字符串
  • t1.txt--> 包含查询中提到的文件内容

相关内容