【问题标题】:Split File while Preserving Groups of Lines [closed]在保留行组的同时拆分文件[关闭]
【发布时间】:2020-01-28 19:54:22
【问题描述】:

我有一个看起来像这样的文本文件

[begin]
line1a
line2a
[end]
[begin]
line1b
line2b
[end]
[begin]
line1c
line2c
[end]

每个组都有相同数量的行(在这种情况下为 4,包括开始和结束标记),并且在一个文件中我有许多这样的行组。

我知道split 命令可以在保留行的同时将文件拆分为 N 个文件,但我想将该文件按行组拆分为 N 个文件。所以在这种情况下,每个输出文件应该只包含完整的 4 行组。例如,要拆分为 2 个文件,输出将是

#file1
[begin]
line1a
line2a
[end]
[begin]
line1b
line2b
[end]

#file2
[begin]
line1c
line2c
[end]

是否有任何 Bash 工具可以做到这一点?

【问题讨论】:

  • 您应该寻找正则表达式解决方案(sed、awk ..)
  • 为什么不是 3 个文件各一组?为什么前两组在一个文件中?
  • @KamilCuk 在示例中,我只想将较大的文件拆分为 2 个文件。如果分成 3 个文件,那么我同意每个文件应该有 1 个组。
  • 哎呀,那为什么不是这样:第一个文件中的一个组,第二个文件中的两个组?你不能只是split -l4 然后合并它们吗?我认为split -l4 -n2 会为指定的输入做你想做的事。
  • @KamilCuk 这对于 3 个组来说似乎是合理的,但该文件可能有数千个组。然后进行合并变得复杂,以使所有结果文件具有大致相同数量的组

标签: bash awk sed split


【解决方案1】:

这可能对您有用(GNU split、csplit、ls、sed 和并行):

csplit -sz file '/^\[begin\]/' '{*}' # split each stanza into a separate file xx??
ls xx?? > k                          # make a list of the above files
split -n l/2 k                       # put each group of files in a new file x??
parallel -q sed -i 's/.*/cat & \&\& rm &/e' ::: x?? # replace x?? with contents
rm k                                 # clean up

概览:

  • file 中的节拆分为单独的文件(xx00, xx01, ....)。
  • 列出这些文件(每行一个)并将其放入名为k 的文件中
  • 将列表k 分成组(在本例中为2)名为xaa, xab, x.. 的新文件,其中包含单独的节文件xx00, xx01, xx.. 的名称
  • 对于每个x?? 文件,将命名节文件xx?? 替换为其内容,然后删除原始文件。
  • 删除k 文件

【讨论】:

  • 使用parallel --pipepart --recstart '[begin]\n' --recend '[end]\n' ...可能会更快
【解决方案2】:

或者,请尝试以下方法:

filename="file"         # assign to your filename
nol=12
gl=4
nof=2

l=$(( (((nol + nof - 1) / nof + gl - 1) / gl) * gl ))
# equals to ceil(ceil(nol / nof) / gl) * gl
digits=${#nof}          # length of suffix number

split -l "$l" -d -a "$digits" "$filename" "$filename"

我遵循了 Cyrus 的变量表示法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多