使用awk格式化文本

daf*_*mat 3 bash shell awk zsh sed

我很难理解如何使用awk实现我想要的东西,经过相当长的一段时间后,我找不到我正在寻找的解决方案.

我有一个输入文本,如下所示:

Some text (possibly containing text within parenthesis).
Some other text
Another line (with something here) with some text
 (
Element 4
)
Another line
 (
Element 1, span 1 to 
Element 5, span 4
)
Another Line 
Run Code Online (Sandbox Code Playgroud)

我想正确格式化'('和')'之间的怪异线条.预期产量如下:

Some text (possibly containing text within parenthesis).
Some other text
Another line (with something here) with some text
(Element 4)
Another line
(Element 1, span 1 to Element 5, span 4)
Another Line 
Run Code Online (Sandbox Code Playgroud)

查看堆栈溢出我发现:
如何选择两个标记模式之间的行,这可能会出现awk/sed多次

所以我现在正在使用的是 echo $text | awk '/ \(/{flag=1;next}/\)/{flag=0}flag'

哪个几乎可以工作,除了它过滤掉不匹配的行,这是最后一个命令产生的输出:

(Element 4)
(Element 1, span 1 to Element 5, span 4)
Run Code Online (Sandbox Code Playgroud)

谁知道怎么做?我愿意接受任何建议,包括不使用awk如果你知道的更好.

如果您教我如何在我的问题代码块上删除语法着色,那么奖励点:)

十亿次感谢

编辑:好的,所以我接受了@ EdMorton的解决方案,因为他使用awk提供了一些东西(好吧,GNU awk).但是,我目前正在使用@ aaron的sed voodoo咒语并取得巨大成功,并且可能会继续这样做,直到我在该特定用例上发现任何新内容.

我强烈建议阅读EdMorton的解释,最后一段是我的一天.如果路过的人有很好的关于awk/sed的资源,他们可以分享,请在评论中随意这样做.

Aar*_*ron 5

以下是我将如何做到这一点GNU sed:

s/^\s*(/(/;/^(/{:l N;/)/b e;b l;:e s/\n//g}
Run Code Online (Sandbox Code Playgroud)

对于那些不说胡言乱语的人来说,意思是:

  • 从以空格和左括号开头的行中删除前导空格
  • 测试该行现在是否以开括号开头.如果是这种情况,请执行以下操作:
    • 将此点标记为标记l,表示循环的开始
    • 从输入到模式空间添加一条线
    • 测试你的模式空间中是否有一个右括号
    • 如果是这样,跳转到标签 e
    • (如果没有)跳转到标签 l
    • 将此点标记为标签e,表示代码的结尾
    • 从模式空间中删除换行符
  • (隐式打印模式空间,是否已被修改)

这可能会被改进,但它可以解决问题:

$ echo """Some text (possibly containing text within parenthesis).
Some other text
Another line (with something here) with some text
 (
Element 4
)
Another line
 (
Element 1, span 1 to
Element 5, span 4
)
Another Line """ | sed 's/^\s*(/(/;/^(/{:l N;/)/b e;b l;:e s/\n//g}'

Some text (possibly containing text within parenthesis).
Some other text
Another line (with something here) with some text
(Element 4)
Another line
(Element 1, span 1 to Element 5, span 4)
Another Line
Run Code Online (Sandbox Code Playgroud)

编辑:如果你可以禁用历史扩展(set +H),这个sed命令更好:s/^\s*(/(/;/^(/{:l N;/)/!b l;s/\n//g}