【问题标题】:Remove line break if line does not start with KEYWORD如果行不以 KEYWORD 开头,则删除换行符
【发布时间】:2012-11-15 01:37:15
【问题描述】:

我有一个平面文件,其中的线条看起来像

KEYWORD|DATA STRING HERE|32|50135|ANOTHER DATA STRING
KEYWORD|STRING OF DATA|1333|552555666|ANOTHER STRING
KEYWORD|STRING OF MORE DATA|4522452|5345245245|REALLY REALLY REALLY REALLY
LONGSTRING THAT INSERTED A LINE BREAK WHEN I WAS EXTRACTING FROM SQLPLUS/ORACLE
KEYWORD|.....

如何删除换行符,以便

KEYWORD|STRING OF MORE DATA|4522452|5345245245|REALLY REALLY REALLY REALLY
LONGSTRING THAT INSERTED A LINE BREAK WHEN I WAS EXTRACTING FROM SQLPLUS/ORACLE

变成

KEYWORD|STRING OF MORE DATA|4522452|5345245245|REALLY REALLY REALLY REALLY LONGSTRING THAT INSERTED A LINE BREAK WHEN I WAS EXTRACTING FROM SQLPLUS/ORACLE

这是在 HP-UNIX 环境中,我可以将文件移动到另一个系统(安装了 powershell 和 ruby​​ 的 windows 盒子)。

【问题讨论】:

  • 可以egrep -v "^KEYWORD" your_file.txt吗?

标签: ruby regex powershell sed awk


【解决方案1】:

我不知道您使用的是什么工具,但是您可以使用此正则表达式匹配每个 \n(或者可能是 \r),而不是 KEYWORD,因此您可以将其替换为 @987654325 @ 你就会拥有它。

DEMO

正则表达式:\r(?!KEYWORD)(带全局修饰符)

【讨论】:

  • 我正在将其复制到 Windows 机器上,并将尝试使用该正则表达式将其替换为 notepad++ 或 ruby​​,具体取决于。谢谢。
  • 如果不是太长的文件,你甚至可以使用我给你的带有演示的页面来替换。
【解决方案2】:

Ruby 的 Array 有一个很好的方法,称为 slice_before,它继承自 Enumerable,在这里可以起到帮助作用:

require 'pp'

text = 'KEYWORD|DATA STRING HERE|32|50135|ANOTHER DATA STRING
KEYWORD|STRING OF DATA|1333|552555666|ANOTHER STRING
KEYWORD|STRING OF MORE DATA|4522452|5345245245|REALLY REALLY REALLY REALLY
LONGSTRING THAT INSERTED A LINE BREAK WHEN I WAS EXTRACTING FROM SQLPLUS/ORACLE
KEYWORD|.....'

pp text.split("\n").slice_before(/^KEYWORD/).map{ |a| a.join(' ') }

=> ["KEYWORD|DATA STRING HERE|32|50135|ANOTHER DATA STRING",
 "KEYWORD|STRING OF DATA|1333|552555666|ANOTHER STRING",
 "KEYWORD|STRING OF MORE DATA|4522452|5345245245|REALLY REALLY REALLY REALLY LONGSTRING THAT INSERTED A LINE BREAK WHEN I WAS EXTRACTING FROM SQLPLUS/ORACLE",
 "KEYWORD|....."]

此代码只是在换行符处拆分您的文本,然后使用slice_before 将结果数组分解为子数组,每个子数组对应以/^KEYWORD/ 开头的文本块。然后它遍历生成的子数组,用一个空格将它们连接起来。任何未预先拆分的行都将被单独保留。被破坏的被重新加入。

在实际使用时,您可能希望将 pp 替换为常规的 puts

至于使用 Ruby 将代码移至 Windows,为什么?在 HP-Unix 上安装 Ruby 并在那里运行它。这是一个更自然的合身。

【讨论】:

    【解决方案3】:

    这个简短的 awk oneliner 应该可以完成这项工作:

    awk '/^KEYWORD/{print ""}{printf $0}' file
    

    【讨论】:

    • +1 用于解决方案(几乎)。如果 $0 包含 printf 格式字符, printf $0 会很糟糕。 printf 的概要是printf format,data,所以这样使用它:printf "%s",$0。您还需要添加一个END{print ""}
    【解决方案4】:

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

    sed ':a;$!{N;/\n.*|/!{s/\n/ /;ba}};P;D' file
    

    在模式空间中保留两行,如果第二行不包含|,则用空格替换换行符并重复,直到它包含或到达文件末尾。

    这里假设最后一个字段是溢出的字段,否则使用KEYWORD 这样的:

    sed ':a;$!{N;/\nKEYWORD/!{s/\n/ /;ba}};P;D' file
    

    【讨论】:

      【解决方案5】:

      Powershell方式:

      [System.IO.File]::ReadAllText( "c:\myfile.txt" ) -replace "`r`n(?!KEYWORD)", ' '
      

      【讨论】:

        【解决方案6】:

        您可以为此使用sedawk(首选) »

        • sed -n 's|\r||g;$!{1{x;d};H};${H;x;s|\n\(KEYWORD\)|\r\1|g;
          s|\n||g;s|\r|\n|g;p}' file.txt

        • awk 'BEGIN{ORS="";}NR==1{print;next;}/^KEYWORD/
          {print"\n";print;next;}{print;}' file.txt


        注意: 将每个命令(sedawk)写成一行

        【讨论】:

        • 啊,sed 脚本的清晰度 :-)。 sed 是用于在单行上进行简单替换的出色工具,对于其他任何内容,只需使用 awk。
        • 只是似乎不值得发布 sed,因为没有人应该这样做。
        • @EdMorton - 我在答案中包含了sed 解决方案,因为问题也被标记为sed
        • 啊,明白了。我的印象是标签中提到的工具是 OP 认为可能解决他的问题的工具,而不是他正在寻找所有这些工具的解决方案,但我知道你来自哪里,谢谢。
        猜你喜欢
        • 2019-10-27
        • 2022-11-24
        • 2015-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-26
        • 1970-01-01
        相关资源
        最近更新 更多