【问题标题】:awk: Join lines based on beginning or ending patternawk:根据开始或结束模式连接线
【发布时间】:2021-01-12 20:32:23
【问题描述】:

我有一个多行文件,其中记录由新行 (\n) 分隔。

每个记录拆分都由一些文本break 标识。

我如何使用 awk 以便如果记录以 break 开头或结尾,它将连接到上一行或下一行,同时保留记录分隔符。

输入($ 代表 EOL)。多个breaks; 可以忽略或视为一个:

A| break;$
B| break;$
C| break;$
D$
E|$
break; FGH|$
break; IJ| break;$
KLM| break;
NOP$

期望的输出:

A|B|C|D$
E|FGH|IJ|KLM|NOP$

当前代码(在 break; 结尾有效,但不将以 break 开头的行加入前一行:

awk '{if (sub(/break;$/,"")) printf "%s", $0; else if (sub(/^break;/,"")) printf $0,"%s"; else print $0}' myfile

我怀疑问题出在 else if 部分,但如果该行以 break; 开头,我无法找出加入前一行的正确语法。

我们将不胜感激,但请仅考虑 awk 解决方案。

更新:

感谢所有贡献的人!下面的建议有效,但似乎一些带有连续break; 的记录仍然会导致问题:

A| break;
B| break;
C| break; break;
break; D$

【问题讨论】:

  • 使用 Perl:perl -0777 -pe 's/ break;\n//g; s/\nbreak; //g' file
  • 如果你觉得红宝石:cat file | ruby -ne 'print $_.gsub(/ *break; */,"").sub("|\n","|")'
  • 在您的示例输入/输出中包含 $ 来表示行尾没有用,因为我们已经可以看到您的行结束位置。它只是成功了,因此我们必须先编辑您的示例以删除$s,然后才能对其进行测试。

标签: awk


【解决方案1】:

你可以试试这个awk:

awk '!/break;|\|$/{print s $0; s=""; next} {gsub(/ *break; */, ""); s = s $0}' file

A|B|C|D
E|FGH|IJ|KLM|NOP

【讨论】:

    【解决方案2】:
    $ awk '{gsub(/ ?break; ?/,""); printf "%s%s", $0, (/\|/ ? "" : ORS)}' file
    A|B|C|D
    E|FGH|IJ|KLM|NOP
    

    【讨论】:

      【解决方案3】:
      awk '/break;|\|$/ {line =line $0;gsub(/ *break; */,"",line);next}{$0 = line $0;print $0;line=""}' file
      A|B|C|D
      E|FGH|IJ|KLM|NOP
      
      

      【讨论】:

        猜你喜欢
        • 2013-10-21
        • 2018-04-13
        • 2018-12-20
        • 2013-05-25
        • 1970-01-01
        • 2018-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多