【问题标题】:How to insert new line between two characters found in regex如何在正则表达式中找到的两个字符之间插入新行
【发布时间】:2021-03-24 17:54:21
【问题描述】:

我正在尝试清理似乎没有将每个新日志条目写入新行的文件。一些条目最终被附加到上一行的末尾。当我尝试使用 grep/awk 等分析和获取正确的计数/数据时,这使得它变得困难......

这是每行/条目的样子 - 请注意,我已经替换了日志条目的实际内容,但基本上每个条目都以相同的字符串开头并以相同的模式结束,ID/字符串后跟一个数字,例如“ID:20”。

图案:

INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: ##

(注意ID后面的数字对于每个条目并不总是相同的)

文件的某些行最终在同一行上有两个条目:

INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 33
INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 20INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 55
INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 20
INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 27INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 14
INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 35INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 22
INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 10

我想做的是在上面第二行的“ID:##”和“INFO”之间为我的文件中受影响的所有行添加一个新行。

我可以通过grep "ID: [0-9]*INFO" mylog.log grep 出现这种情况的所有链接

并尝试了许多 sed 命令,但似乎无法弄清楚如何在数字 [0-9]* 和 INFO 之间偷偷插入新行 '\n'...

感谢任何帮助。

【问题讨论】:

    标签: linux awk sed


    【解决方案1】:

    鉴于发布的示例输入/输出,您所需要的只是使用具有 -E 的 sed 来启用 ERE 并在替换文本中支持 \n 表示“换行符”(例如 GNU 和 OSX/BSD seds):

    $ sed -E 's/([0-9]+)INFO/\1\nINFO/g' file
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 33
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 20
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: ##
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 20
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 27
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: ##
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 35
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 22
    INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 10
    

    或者在每个 Unix 机器上的任何 shell 中使用任何 sed:

    sed 's/\([0-9][0-9]*\)INFO/\1\
    INFO/g' file
    

    如果这对您不起作用,请修复您的示例以包含不起作用的情况。

    【讨论】:

      【解决方案2】:

      使用grep 你可以这样做:

      grep -Eo 'INFO:[[:blank:]].*?ID:[[:blank:]][0-9]+' file
      
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 33
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 20
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 55
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 20
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 27
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 14
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 35
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 22
      INFO: DATA: ## DATA2 ## DATA3: ##.### DATA4: ## ID: 10
      

      【讨论】:

      • .*? 在我看来有点 PCRE 风格。至少在 ERE 中这是未定义的行为。
      • "undefined" 并不意味着它不会在某些 Unix 机器上的某些 shell 中使用某些版本的工具从某些输入中产生您期望的输出,它只是意味着您可以/将会有不同的根据工具实现者决定如何实现非 POSIX 功能,会导致不同的情况。
      • FWIW 当我在 cygwin 的 bash 中使用 GNU grep 运行该命令时,它会输出未修改的输入。
      • 使用gnu grep 我相信我们需要使用-P 而不是-E
      • 对,.*? 是 PCRE 主义,-P 在 GNU grep 中启用 PCRE。只是未定义任何没有启用 PCRE 选项的 grep 将如何处理.*?-E 选项不启用 PCRE,仅启用 ERE,因此 YMMV 具有那种欲望,就像你不使用 -E 一样。
      【解决方案3】:

      对此的一种懒惰方法是,当您注意到“INFO”不在最左侧位置时首先插入新行,然后将其通过管道传输到正则表达式模式检查器以确保它符合 DATA...DATA4 账单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-25
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多