【问题标题】:Using regex to tell csplit where to split the file使用正则表达式告诉 csplit 在哪里拆分文件
【发布时间】:2019-08-06 04:11:46
【问题描述】:

我有一个大文本文件,其内容设置如下:

---
title: Lorim Ipsum Dolar
---
Lorim ipsum content
---
title: Excelvier whatever 
---
Lorim ipsum content goes here.

我正在尝试使用 csplit 将此文件拆分为单独的文件。

单个文件的内容格式如下:

---
title: Lorim Ipsum Dolar
---
Lorim ipsum content

我希望能够像---\ntitle那样正则表达式---、换行符和标题

但我无法选择它...

csplit -k products.txt '/---[^\n]title/' {99}

我尝试了很多变化都无济于事。我不断收到“不匹配”。

【问题讨论】:

  • 我不知道csplit,但你试过/---[\r\n]+title/ 吗? ([^ ...] 是一个否定类,有时会有回车和换行符)。

标签: regex bash bsd csplit


【解决方案1】:

您可以使用匹配到行尾的正则表达式 ($)

你怎么看:

csplit -k products.txt '/^title:/' {99}

【讨论】:

  • 我希望它可以进行多线交易,但这确实有效。
【解决方案2】:

csplit 一次读取输入文件一行并将正则表达式应用于每一行。因此,不可能跨多行匹配一个正则表达式。

解决此问题的一种方法是先处理输入文件,将---\ntitle: 替换为 csplit 可以匹配的单行模式。例如,使用 sed:

sed 'N;s/---\ntitle: /===\n' products.txt | csplit -k - '/===/' {*}
sed 'N;s/===\n/---\ntitle: /' -i xx*

这会将---\ntitle: 替换为单行===,然后在看到该模式时进行 csplit 拆分。传递 - 作为文件名告诉 csplit 从标准输入读取。第二个 sed 命令反转更改。

【讨论】:

    【解决方案3】:

    尝试使用{*} 而不是{99} 来解决match not found 问题。

    【讨论】:

    • 我相信{99} 只是告诉csplit 重复该过程的时间。无论如何,在我的 BSD 版本中,{*} 是行不通的。见stackoverflow.com/questions/4323703/…
    • @PhilipMeissner 这很有趣。在 debian 下 csplit 总是会尝试查找指定数量的匹配项,如果找不到 99 个匹配项,则会抛出错误。 csplit --versioncsplit (GNU coreutils) 8.21
    【解决方案4】:

    这可能对你有用:

    csplit -z products.txt '/^title/-1' '{*}'
    

    【讨论】:

      【解决方案5】:

      对我来说,答案是不要使用csplit,使用awk

      awk '
      /^title:/ {++count; file="file"count".txt"; print file}
      file {print line > file}
      {line=$0}
      ' products.txt
      

      第一个命令在遇到title: 时声明一个新文件。如果声明了file,第二个命令将前面的 行写入file。第三个命令将当前行分配给一个变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-02
        • 1970-01-01
        • 2022-01-17
        • 2021-04-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多