如何将包含许多记录的文件拆分为较小的记录组

时间:2020-03-26 15:41:09

标签: python linux bash split

如何将包含许多记录的文件分成以下较小的文件,每个文件包含较少的记录?

<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,但我并不熟悉。 有一个简单的解决方案可以解决这个非常简单的任务吗?

1 个答案:

答案 0 :(得分:1)

好吧,我不得不自己玩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

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

请尽情享受!