两个文件:
档案1
{
foo
}
{
bar
}
文件2
foo
}
{
bar
}
(唯一的区别是文件1以开放大括号开始)
以下表达式适用于文件2,但不适用于文件1,为什么? (以及如何解决?):
sed '1!N; s/}\n{/},\n{/' < file1 or file2
我不知道为什么打开大括号,匹配前2行会导致这种行为。我想知道为什么sed被绊倒以及如何解决它的原因。但是,除了sed之外,我还可以通过其他方式在,
之间插入}\n{
。
答案 0 :(得分:4)
这是你想要的(使用GNU awk进行多字符RS):
$ awk -v RS='}\n{' '{ORS=(RT?"},\n{":"")} 1' file1
{
foo
},
{
bar
}
$ awk -v RS='}\n{' '{ORS=(RT?"},\n{":"")} 1' file2
foo
},
{
bar
}
答案 1 :(得分:3)
它不是开口支撑,它是额外的线。将任何放在该行上(即使没有),您的脚本就会停止工作。
您的脚本严格基于对。它仅在结束ttk::style element create pin vsapi EXPLORERBAR 3 {
{pressed !selected} 3
{active !selected} 2
{pressed selected} 6
{active selected} 5
{selected} 4
{} 1
}
ttk::style layout Explorer.Pin {Explorer.Pin.pin -sticky news}
pack [ttk::checkbutton .pin -style Explorer.Pin]
落在偶数行时才有效。
您的Sed脚本显示}
- 对于不在第一行的每一行,将 next 行读入模式空间,然后尝试1!N
转化
然后脚本结束,Sed打印模式空间,丢弃它,并读取下一行。你只能从第二行开始一次配对两行。
的文件
s///
也不会被正确修改,但是
}
{
意愿。
这个Sed命令
f
}
{
适用于不包含sed '/}$/{N;s/}\n{/},\n{/}'
的文件(它会错过这些文件)。
对于更强大的内容,您需要}\n}\n{
之类的内容或awk
更好的内容,而不是我想出更聪明的脚本。
答案 2 :(得分:2)
这可能适合你(GNU sed):
sed '1b;$!N; s/}\n{/},\n{/;P;D' file
目前,您正在处理成对的行之后,您想要使用两行窗口遍历文件。
这将使两行窗口一次又一行地撞击文件的末尾,即它删除第一行但保留第二行然后将下一行附加到该行。要查看它是如何工作的(并且通常对所有sed脚本都有用),请使用l
命令:
sed '1b;$!N;l;s/}\n{/},\n{/;P;D' file
答案 3 :(得分:1)
Etan Reisner's answer很好地解释了sed
命令的问题。
通常,awk
可以更轻松地解析跨越行。
假设 GNU awk
或mawk
,请尝试以下操作:
awk -v RS='\n}\n{' '/\}\n$/ { printf "%s", $0; next; } { printf "%s\n},\n{", $0 }' file
顶级域内的嵌套{...}
序列是可以的,只要它们的结束}
缩进。
RS='\n}\n{'
表示输入被\n}\n{
序列分成记录 - 跨行。
RS
值是POSIX standard的扩展名,GNU Awk和Mawk恰好实现了这一点; BSD Awk,也用于OS X,不。/\}\n$/
仅匹配 last 记录,因为后面没有其他{
:
printf "%s", $0
只是按原样打印;它的开头{
(如果有的话)是在上一条记录的上下文中打印出来的,如果有的话。,
和下一个记录的开头}
之间插入{
:{ printf "%s\n},\n{", $0 }