[英]Replace several lines by one using sed
我有这样的输入:
This_is(A)
Goto(B,condition_1)
Goto(C,condition_2)
This_is(B)
Goto(A,condition_3)
This_is(C)
Goto(B,condition_1)
我想让它变成这样
(A,B,condition_1)
(A,C,condition_2)
(B,A,condition_3)
(C,B,condition_1)
有人知道如何用sed做到这一点吗?
假设你真的不需要用 sed 来做这件事,这将在每个 UNIX 机器上的任何 shell 中使用任何 awk 工作:
$ awk -F'[()]' '/^[^[:space:]]/{s=$2; next} {sub(/[^[:space:]]*\(/,"("s",")} 1' file
(A,B,condition_1)
(A,C,condition_2)
(B,A,condition_3)
(C,B,condition_1)
这是一个可能的sed
解决方案,我在其中硬编码了一些位,例如This_is
和Goto
因为 OP 没有说明这些字符串是否在实际文件中沿文件发生变化:
sed '/^This_is/{:a;N;s/\(^This_is(\(.\)).*\)\(\n *\)Goto(\([^)]*)\)$/\1\3(\2,\4/;$!ta;s/[^\n]*\n//}' input_file
(不幸的是,对于所有这些括号,使用-E
并不会缩短命令的长度。)
如果拆分成更多行,代码可读性会更高:
sed '/^This_is/{
:a
N
s/\(^This_is(\(.\)).*\)\(\n *\)Goto(\([^)]*)\)$/\1\3(\2,\4/
$!ta
s/[^\n]*\n//
}' os
在这里您可以看到代码仅在以This_is
开头的行上This_is
; 当程序遇到这些行时,它会执行以下操作。
N
命令将下一行附加到模式空间(穿插\\n
s),s/…/…/
,基本上试图挑x
在This_is(x)
并把它刚刚过去的后Goto(
上多,s
成功,则ta
分支到:a
)并且最后一行还没有被读取( $!
匹配除最后一行之外的所有行);
:a
标记了入口点,如果 while 条件为真,则控制跳转回,而ta
是评估逻辑条件的命令。s/…/…/
This_is
命令从多行模式空间中删除前导行,即This_is
行。这可能对你有用(GNU sed):
sed -E '/^\S.*\(.*\)/{h;d};G;s/\S+\((.*\))\n.*(\(.*)\).*/\2,\1/;P;d' file
如果一行以非空白字符开头并包含括号,请将其复制到保留空间 (HS),然后将其删除。
否则,附加 HS,删除起始括号之前的非白色字符,从存储的值中插入括号之间的值,添加逗号并打印第一行,然后删除整个模式空间。
不符合替代标准的 NB 行将保持不变。
使用 GNU 并行和 sed 的替代解决方案:
parallel --pipe --recstart T -kqN1 sed -E '1{h;d};G;s/\S+\((.*)\n.*(\(.*)\).*/\2,\1/;P;d' <file
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.