Regex 使用SED删除地址范围的换行符
我很难让我的SED脚本正常工作。它似乎只在第一次出现时起作用。我基本上是一个UNIX初学者-请容忍我 数据文件如下所示:Regex 使用SED删除地址范围的换行符,regex,sed,Regex,Sed,我很难让我的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
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/{
:a
N
$!ba
s/\n//
}
以“exec cics”开头并以“end exec”结尾的所有内容都应位于一行,并删除任何换行符
SED脚本如下:
exec cics end-exec.
exec cics send map end-exec.
exec cics end-exec.
/exec cics/,/end-exec/{
:a
N
$!ba
s/\n//
}
我从这里得到了花括号中的代码:
我最初的脚本没有
:a;N、 美元!ba
。有人能看到我遗漏了什么或做错了什么吗?如果你想试试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
开头,而不是第一行,则在该行之前添加换行符。否则,只需在一行中打印数据。如果您想尝试
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
开头,而不是第一行,则在该行之前添加换行符。否则,只需在一行中打印数据。您得到的结果可以解释为您只替换了第一个换行:
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
您得到的结果可以通过仅替换第一个换行来解释:
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
您的
sed
脚本的此修改版本似乎可以完成以下任务:
/exec cics/,/end-exec/{
:a
/end-exec/! N
s/\n/ /g
t a
}
当保存在文件sed.script
中并给定数据文件(data2
)时:
(任何数据行上都没有尾随空格),然后我得到:
$ 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上进行测试。此修改版的sed
脚本似乎可以完成以下任务:
/exec cics/,/end-exec/{
:a
/end-exec/! N
s/\n/ /g
t a
}
当保存在文件sed.script
中并给定数据文件(data2
)时:
(任何数据行上都没有尾随空格),然后我得到:
$ 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上进行测试。您应该注意,X-ref的问题使用s/\n//g
而不是s/\n//
。您应该注意,X-ref的问题使用s/\n//g
而不是s/\n/
+1进行解释(并使其与BSD一起工作:))。不过,解决方案中的g
标志是多余的,因为我们每次在追加下一行后都会运行替换。@jaypal:是的,替换上的全局后缀不需要,尽管它不太可能造成可测量的伤害。我想有一个版本的剧本需要它,但那是很久以前的事了,现在我记不清了。当然,它的出现不会造成任何伤害。我只是在想,与其对每一行都进行替换,不如先构建整个行,然后只进行一次全局替换,这是一种更好、更便宜的方法。由提出的第二个解决方案似乎就是这样做的,尽管它只是GNUsed
。+1用于解释(以及使它与BSD一起工作:))。不过,解决方案中的g
标志是多余的,因为我们每次在追加下一行后都会运行替换。@jaypal:是的,替换上的全局后缀不需要,尽管它不太可能造成可测量的伤害。我想有一个版本的剧本需要它,但那是很久以前的事了,现在我记不清了。当然,它的出现不会造成任何伤害。我只是在想,与其做替换,不如