这个问题来自于 如何删除多行文本文件中大括号之间的所有文本?(完全一样,但没有嵌套要求)。
例:
This is {
{the multiline
text} file }
that wants
{ to {be
changed}
} anyway.
应成为:
This is
that wants
anyway.
是否可以通过某种单行bash命令(awk,sed,perl,grep,cut,tr ...等)来执行此操作?
这个问题来自于 如何删除多行文本文件中大括号之间的所有文本?(完全一样,但没有嵌套要求)。
例:
This is {
{the multiline
text} file }
that wants
{ to {be
changed}
} anyway.
应成为:
This is
that wants
anyway.
是否可以通过某种单行bash命令(awk,sed,perl,grep,cut,tr ...等)来执行此操作?
Answers:
$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file3
This is
that wants
anyway.
说明:
:again;$!N;$!b again
这将读取整个文件。
:again
是一个标签。 N
在$!N
我们还不在最后一行的条件下,在下一行读取,并在下一行读取。 如果这不是最后一行,则$!b again
分支返回again
标签。
:b
这定义了一个标签b
。
s/{[^{}]*}//g
只要文本不包含内部大括号,这将删除大括号中的文本。
t b
如果上述替代命令导致更改,请跳回到label b
。以此方式,替换命令将重复执行,直到除去所有大括号组为止。
Perl方法:
$ perl -F"" -a00ne 'for (@F){$i++ if /{/; $i||print; $i-- if /}/}' file
This is
that wants
anyway
-a
:关于由给定的文件定界符自动分割轮流-F
进入@F
阵列。-F""
:将输入字段分隔符设置为空,这将导致每个元素@F
成为输入字符之一。-00
:打开“段落模式”,其中将“行”定义为两个连续的换行符。这意味着在这种情况下,整个文件将被视为一行。如果您的文件可以包含多个段落,并且括号可以跨多个段落,请-0777
改用。-ne
:读取输入文件,然后将给定的脚本-e
应用于每一行。脚本本身实际上非常简单。每次{
看到a时,计数器将增加一个,然后将a 减1 }
。这意味着当计数器为0时,我们不在方括号内,应该打印:
for (@F){}
:对@F
,行中每个字符的每个元素执行此操作。$i++ if /{/;
:$i
如果此字符为a,则加1{
$i||print;
:除非$i
设置,否则打印(0视为未设置)。$i-- if /}/
:$i
如果此字符是一个减1}