rod*_*igo 10 sed text-processing
我有这个文件:
sometext1{
string1
}
sometext2{
string2
string3
}
sometext3{
string4
string5
string6
}
Run Code Online (Sandbox Code Playgroud)
我想在此文件中搜索特定字符串并打印此字符串之前到开头的{
所有内容以及此字符串之后到结尾的所有内容}
。我试图用 sed 来实现这一点,但如果我尝试打印范围内的所有内容,/{/,/string2/
例如 sed 打印:
sometext1{
string1
}
sometext2{
string2
sometext3{
string4
string5
string6
}
Run Code Online (Sandbox Code Playgroud)
如果我搜索字符串“string2”,我需要输出为:
sometext2{
string2
string3
}
Run Code Online (Sandbox Code Playgroud)
谢谢。
mik*_*erv 10
这里有两个命令。如果您想要一个可以修剪到.*{$
序列中最后一行的命令(如 @don_crissti 对ed
),您可以执行以下操作:
sed 'H;/{$/h;/^}/x;/{\n.*PATTERN/!d'
Run Code Online (Sandbox Code Playgroud)
...它的工作原理是将每一行附加到ewline 字符H
后面的旧空间,为匹配的每一行\n
覆盖h
旧空间{$
,并为匹配的每一行交换h
旧空间和模式空间^}
- 从而刷新其缓冲区。
它只打印匹配该行{
再\n
ewline,然后PATTERN
在某个时刻-这只是没有发生过紧跟在缓冲交换。
它将一系列{$
匹配中的任何行删除到序列中的最后一行,但您可以获得所有这些行,例如:
sed '/PATTERN.*\n/p;//g;/{$/,/^}/H;//x;D'
Run Code Online (Sandbox Code Playgroud)
它所做的是h
为每个...{$.*^}.*
序列交换模式和旧空间,将序列中的所有行附加到ewline 字符H
之后的旧空间\n
,并在每个行循环中删除模式空间中D
第一个出现的\n
ewline 字符,然后再从剩余的开始。
当然,它\n
在模式空间中获得ewline的唯一时间是当输入行匹配时^}
- 范围的末尾 - 因此当它在任何其他情况下重新运行脚本时,它通常只会拉入下一个输入行。
但是,当PATTERN
在与\n
ewline相同的模式空间中找到时,它会在^}
再次覆盖之前打印批次(因此它可以结束范围并刷新缓冲区)。
鉴于此输入文件(感谢唐):
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
}
}
Run Code Online (Sandbox Code Playgroud)
第一个打印:
sometext2{
PATTERN
string3
}
sometext4{
some string
string unknown
here's PATTERN and PATTERN again
and PATTERN too
another string here
}
Run Code Online (Sandbox Code Playgroud)
……第二个……
sometext2{
PATTERN
string3
}
Header{
sometext4{
some string
string unknown
here's PATTERN and PATTERN again
and PATTERN too
another string here
}
Run Code Online (Sandbox Code Playgroud)
这是一个解决方案ed
:
ed -s filename <<< $'g/PATTERN/?{?,/}/p\nq\n'
Run Code Online (Sandbox Code Playgroud)
那是:
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
Run Code Online (Sandbox Code Playgroud)
这假设PATTERN
每对之间只有一条线,{
}
否则对于PATTERN
同一块内的每条附加线,您将获得重复的输出。
它将适用于{
}
包含单行匹配的多个,PATTERN
例如具有PATTERN
两个不同部分的测试文件:
sometext1{
string1
}
sometext2{
PATTERN
string3
}
sometext3{
string4
string5
string6
}
Header{
sometext4{
some string
string unknown
here's PATTERN again
another string here
}
}
Run Code Online (Sandbox Code Playgroud)
跑步
ed -s sample <<< $'g/PATTERN/?{?,/}/p\nq\n'
Run Code Online (Sandbox Code Playgroud)
输出:
sometext2{
PATTERN
string3
}
sometext4{
some string
string unknown
here's PATTERN again
another string here
}
Run Code Online (Sandbox Code Playgroud)