首页 > 解决方案 > 如何将包含许多记录的文件拆分为较小的记录组

问题描述

如何将包含许多记录的文件拆分为较小的文件,每个文件包含较少数量的记录?

<TAG>
Record_1
</TAG>
<TAG>
Record_2
</TAG>
<TAG>
Record_3
</TAG>
<TAG>
Record_4
</TAG>
<TAG>
Record_5
</TAG>

当然,我们谈论的是非常大的数字。目标是将此文件拆分为较小的文件,但不是每个文件一个记录,就像我们经常看到的使用csplit. 例如,这里我们希望每个文件有 2 条记录(但可能是 100 条或更多)。

所以预期的结果是:

split1

<TAG>
Record_1
</TAG>
<TAG>
Record_2
</TAG>

split2

<TAG>
Record_3
</TAG>
<TAG>
Record_4
</TAG>

split3

<TAG>
Record_5
</TAG>

如果无法使用标准命令行,我可能会考虑编写几行 python,但我不熟悉它。这个非常简单的任务有一个简单的解决方案吗?

标签: pythonlinuxbashsplit

解决方案


好吧,我不得不自己玩python。这是一个简单且可重用的解决方案(当然可以改进,但效果很好)。

#!/usr/bin/python3
import sys, re, argparse

# config
parser = argparse.ArgumentParser(description='Split file into smaller ones, each one containing N blocs delimited by regexp')
parser.add_argument('inputf', metavar='FILE', type=argparse.FileType('r'),
                    help='the input file to split')
parser.add_argument('regexp', metavar='REGEXP',
                    help='the regular expression matching start of a new bloc')
parser.add_argument('--repeat', type=int, default=1, metavar='N',
                    help='the number of blocs to add per file')
parser.add_argument('--prefix', default='split_',
                    help='the prefix of generated files')
parser.add_argument('--suffix', default='.txt',
                    help='the suffix of generated files')
args = parser.parse_args()

# function
def split_file(fdin, regexp, repeat=1, prefix='split_', suffix='.txt'):
    nFile=0
    nMatch=0

    # Read file line by line
    for i, line in enumerate(fdin):
        # Check if regexp match
        if re.match(regexp, line):
            nMatch+=1

        # Increase file suffix
        if ( nMatch >= repeat ):
            nFile+=1
            nMatch=0

        # Write lines to file
        with open(f"{prefix}{nFile:03}{suffix}", "a") as fdout:
            fdout.write(line)

# run
split_file(args.inputf, args.regexp, args.repeat, args.prefix, args.suffix)

用法非常简单,如argparse.

./split.py -h
usage: split.py [-h] [--repeat REPEAT] [--prefix PREFIX] [--suffix SUFFIX]
                FILE REGEXP

Split file into smaller ones, each one containing N blocs delimited by regexp

positional arguments:
  FILE             the input file to split
  REGEXP           the regular expression matching start of a new bloc

optional arguments:
  -h, --help       show this help message and exit
  --repeat N       the number of blocs to add per file
  --prefix PREFIX  the prefix of generated files
  --suffix SUFFIX  the suffix of generated files

因此,给定示例的答案是: ./split.py input.xml '<TAG>' --repeat 2

-请注意,如果提供输入文件代替文件,则输入文件也可以是标准输入。

如果你找到这个,请尽情享受!


推荐阅读