这是我的具体任务。我有以下类型的模式
.*[class|namespace|struct].*
(准确地说,这是图案的一部分),
然后任意数量的换行符\n
或空格混合在一起(可能是 0 个换行符,但至少有 1 个空格),之后我有一个非常具体的模式 - 我基本上知道这一行总是会挡住
{specific_text;^
这是该模式的第二部分。就是这样。
注意:如果存在模式的第一部分,那么肯定存在第二部分。
任务
我需要将每一行替换为相应部分一模式之前的自定义文本,并将其替换为单个花括号和换行符,如下所示 - ''{\n''。
如何使用 bash shell、awk 和 sed 来完成此操作?
注意。因此,您可以看到,基本上我想更改与我的特定模式匹配的第一行,并且它是 class|namespace|struct 关键字之后同类中的第一个。
例子。
class A { specific_text;
转化为
class A {
和这个
class A
{ specific_text;
变成
class A
{
请注意,在最后一个例子中我们保留了换行符。
答案1
sed '/class\|namespace\|struct/ {
: loop
s/{ *specific_text;$/{/
t
n
b loop
}'
它的工作原理如下:
- 直到找到
class
或namespace
或,它只执行其默认操作:按原样打印传入的行。struct
sed
- 当找到
class
或或namespace
时,进入循环。struct
sed
: loop
是一个标签,循环的开始。b loop
分支到标签,这是循环的结束。- 有两种方法可以退出循环:
- 输入结束,
t
分支到脚本的末尾。
t
仅当上述操作s
成功时才会起作用。- 如果
t
不起作用,脚本将继续n
打印当前行并移动到下一行。
换句话说,循环的外部和内部都会打印传入的行,但只有在循环中我们尝试用 进行替换时才会打印s
。成功替换后将退出循环。如果遇到另一个class
或namespace
或 ,该工具将再次循环。struct
换句话说,这正是你想要的(我认为):
更改与我的非常特定的模式匹配的第一行,并且它是 class|namespace|struct 关键字之后同类中的第一个。
笔记:
- 脚本并不关心
class
(或namespace
或struct
)与特定模式之间是什么。 - 我调整了你的模式。特别是
- 我在
{
和之间留有空格,specific_text
因为您的测试用例有空格; - 我使用了
$
而不是^
,因为^
在你的模式中是文字,它没有任何意义(也许你混淆了^
和$
锚点)。
输入示例:
foo
bar
class A { specific_text;
baz { specific_text;
qux
this is my namespace
whatever
abc {specific_text;
foo
{ specific_text;
{specific_text;
输出:
foo
bar
class A {
baz { specific_text;
qux
this is my namespace
whatever
abc {
foo
{ specific_text;
{specific_text;
修改后的行:
class A { specific_text;
abc {specific_text;
(因为namespace
之前有几行)