我在使SED脚本正常工作时遇到了一些困难。它似乎只适用于第一次出现。我基本上是UNIX初学者 - 请耐心等待。
数据文件如下所示:
exec cics
end-exec.
exec cics
send map
end-exec.
exec cics
end-exec.
实际输出如下所示,并且只在第一次出现时才能正常工作:
exec cics end-exec.
exec cics
send map
end-exec.
exec cics
end-exec.
所需的输出应如下:
exec cics end-exec.
exec cics send map end-exec.
exec cics end-exec.
以" exec cics"开头的一切并以" end-exec"结束应该在一行上删除任何新行。
SED脚本如下:
/exec cics/,/end-exec/{
:a
N
$!ba
s/\n//
}
我从这里获得了大括号内的代码:How can I replace a newline (\n) using sed?
我的初始脚本没有:a;N;$!ba
。谁能看到我遗失或做错了什么?
答案 0 :(得分:2)
您获得的结果可以通过仅替换第一个换行符来解释:
s/\n//
但是,即使您在全球范围内执行了替换,即使用了:
s/\n//g
你会得到:
exec cics end-exec. exec cics send map end-exec. exec cics end-exec.
因为$
地址与文件中最后一次出现的匹配。
除非您匹配最后一行,否则不要分支到标签a
,而是在遇到end-exec
时不要分支。话说:
sed '/exec cics/,/end-exec/{:a;N;/end-exec/!ba;s/\n/ /g}' filename
会产生:
exec cics end-exec.
exec cics send map end-exec.
exec cics end-exec.
如果您的输入包含从exec cisc
开始并以end-exec
开头的连续块,则可以简化它:
sed ':a;N;/end-exec/!ba;s/\n/ /g' filename
答案 1 :(得分:1)
如果您想尝试awk
awk '{printf (/exec cics/ && NR>1?RS:"")"%s",$0} END {print ""}'
exec cics end-exec.
exec cics send mapend-exec.
exec cics end-exec.
如果行以exec cics
开头而不是第一行,请在该行之前添加换行符
否则,只需将数据打印在一行中即可。
答案 2 :(得分:1)
sed
脚本的这个修改版似乎可以完成这项工作:
/exec cics/,/end-exec/{
:a
/end-exec/! N
s/\n/ /g
t a
}
保存在文件sed.script
中,并提供数据文件(data2
):
exec cics
end-exec.
exec cics
send map
end-exec.
exec cics
end-exec.
exec cics
do this
and that
and tother
end-exec.
(任何数据行都没有尾随空白),然后我得到:
$ sed -f sed.script data2
exec cics end-exec.
exec cics send map end-exec.
exec cics end-exec.
exec cics do this and that and tother end-exec.
$
脚本有什么作用?
exec cics
和end-exec
之间的每个行范围,a
,end-exec
,则添加另一行。a
。在调试/设计时,我在t
之后和}
之前添加了几行:
s/^/[[/
s/$/]]/
这有助于我了解如何使用各种其他版本的命令处理数据,包括原始版本;这些行在打印时被[[
和]]
括起来。
使用提供的BSD sed
在Mac OS X 10.9.2 Mavericks上进行测试。