【问题标题】:Multiline string search output into one line多行字符串搜索输出到一行
【发布时间】:2026-01-11 09:45:01
【问题描述】:

我有一个带有开始和结束标记的字符串,我想在一行上打印出来。 案例是:

  • 一个字符串可能会出现在一行中 - 保持原样。
    • 一个字符串可以出现在多行 - 合并为一行。
    • 结束标记可以出现在多行中 - 合并为一行。

比如我要改造:

(start) AAAA 
(the end)

(start) BBBB (the end)
(start) CCCC (the 
end)

进入输出:

(start) AAAA (the end)
(start) BBBB (the end)
(start) CCCC (the end)

目前我有这个:

awk '/^\(start\)/{printf $0" ";next;}1' test.text

(start) AAAA  (the end)

(start) BBBB (the end) (start) CCCC (the  end)

这个命令的问题是:

  • AAAA 之后的额外空格。
  • BBBB 和 CCCC 在同一条线上。
  • 最后的结束标记有一个额外的空间。

对此有什么好的工具和解决方案? 对于正确方向的指针,我会很高兴。

【问题讨论】:

  • 如果这真的是一个 html 文件,最好花时间学习 html 漂亮打印实用程序的选项,例如 tidy。祝你好运。
  • 我向你保证它不是 HTML,谢谢。

标签: linux string awk sed grep


【解决方案1】:

不是立即打印该行,而是将行内容收集到一个变量中。到达结束标记时,删除多余的空格并打印。

awk '{ var = var " " $0 }
     var ~ /\(the +end\)/ { sub(/^ +/, "", var); gsub(/ +/, " ", var); print var; var="" }
    ' test.text

【讨论】:

    【解决方案2】:

    请您尝试一下(这个不会处理不均匀的空间)。

    awk  'NF{printf("%s%s",$0,$0!~/\(the end\)$/?OFS:ORS)}'  Input_file
    

    要获得适当的空间,请尝试:

    awk  'NF{$1=$1;printf("%s%s",$0,$0!~/\(the end\)$/?OFS:ORS)}' Input_file
    

    输出如下。

    (start) AAAA (the end)
    (start) BBBB (the end)
    (start) CCCC (the end)
    

    【讨论】:

    • @user1330734,你能检查一下上面然后告诉我吗?
    【解决方案3】:

    这可能对你有用(GNU sed):

    sed '/(start).*(the end)/b;/(start)/{:a;N;s/\n//;/(the end)/!ba}' file
    

    如果一行包含开始和结束条件,则打印它。否则,如果一行包含开始条件,则附加以下行,删除它们之间的换行符并测试结束条件。如果结束条件的测试失败,则重复,否则打印当前修改的行。

    在原始问题中,预期的解决方案还删除了空行,这可以添加到 i.e.

    sed '/\S/!d;/(start).*(the end)/b;/(start)/{:a;N;s/\n//;/(the end)/!ba}' file
    

    另一种略短的解决方案:

    sed '/\S/!d;/(start)/{:a;/(the end)/!{N;s/\n//;ba}}' file
    

    【讨论】: