App-CSVUtils

 view release on metacpan or  search on metacpan

lib/App/CSVUtils/csv_split.pm  view on Meta::CPAN

package App::CSVUtils::csv_split;

use 5.010001;
use strict;
use warnings;

our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2026-07-09'; # DATE
our $DIST = 'App-CSVUtils'; # DIST
our $VERSION = '1.038'; # VERSION

use App::CSVUtils qw(
                        gen_csv_util
                );

gen_csv_util(
    name => 'csv_split',
    summary => 'Split CSV file into several files',
    description => <<'MARKDOWN',

Will output split files xaa, xab, and so on. Each split file will contain a
maximum of `lines` rows (options to limit split files' size based on number of
characters and bytes will be added). Each split file will also contain CSV
header.

Warning: by default, existing split files xaa, xab, and so on will be
overwritten.

Interface is loosely based on the `split` Unix utility.

MARKDOWN
    add_args => {
        lines => {
            schema => 'posint*',
            default => 1000,
            cmdline_aliases => {l=>{}},
        },
        # XXX --bytes (-b)
        # XXX --line-bytes (-C)
        # XXX -d (numeric suffix)
        # --suffix-length (-a)
        # --number, -n (chunks)
    },
    tags => ['category:splitting'],

    examples => [
        {
            summary => 'Split CSV files to xaa, xab, ... where each split file gets 1000 rows',
            argv => ['file.csv'],
            test => 0,
            'x.doc.show_result' => 0,
        },
    ],

    writes_multiple_csv => 1,

    before_read_input => sub {
        my $r = shift;

        $r->{output_filenames} = ['xaa'];
        $r->{output_num_of_files} = '?';
    },

    on_input_data_row => sub {
        my $r = shift;

        # time to switch to another file?
        if ($r->{input_data_rownum} > 1 && ($r->{input_data_rownum}+1) % $r->{util_args}{lines} == 0) {
            $r->{wants_switch_to_next_output_file}++;
            my $next_filename = $r->{output_filenames}[-1];
            $next_filename++;
            push @{ $r->{output_filenames} }, $next_filename;
        }

        $r->{code_print_row}->($r->{input_row});
    },
);

1;
# ABSTRACT: Split CSV file into several files

__END__

=pod

=encoding UTF-8

=head1 NAME

App::CSVUtils::csv_split - Split CSV file into several files

=head1 VERSION

This document describes version 1.038 of App::CSVUtils::csv_split (from Perl distribution App-CSVUtils), released on 2026-07-09.

=head1 FUNCTIONS


=head2 csv_split

Usage:

 csv_split(%args) -> [$status_code, $reason, $payload, \%result_meta]

Split CSV file into several files.

Examples:

=over

=item * Split CSV files to xaa, xab, ... where each split file gets 1000 rows:

 csv_split(input_filename => "file.csv");

=back

Will output split files xaa, xab, and so on. Each split file will contain a
maximum of C<lines> rows (options to limit split files' size based on number of
characters and bytes will be added). Each split file will also contain CSV
header.

Warning: by default, existing split files xaa, xab, and so on will be
overwritten.

Interface is loosely based on the C<split> Unix utility.

This function is not exported.

Arguments ('*' denotes required arguments):

=over 4

=item * B<inplace> => I<true>

Output to the same file as input.

Normally, you output to a different file than input. If you try to output to the
same file (C<-o INPUT.csv -O>) you will clobber the input file; thus the utility
prevents you from doing it. However, with this C<--inplace> option, you can
output to the same file. Like perl's C<-i> option, this will first output to a
temporary file in the same directory as the input file then rename to the final
file at the end. You cannot specify output file (C<-o>) when using this option,
but you can specify backup extension with C<-b> option.

Some caveats:

=over

=item * if input file is a symbolic link, it will be replaced with a regular file;

=item * renaming (implemented using C<rename()>) can fail if input filename is too long;

=item * value specified in C<-b> is currently not checked for acceptable characters;

=item * things can also fail if permissions are restrictive;

=back

=item * B<inplace_backup_ext> => I<str> (default: "")

Extension to add for backup of input file.

In inplace mode (C<--inplace>), if this option is set to a non-empty string, will
rename the input file using this extension as a backup. The old existing backup
will be overwritten, if any.

=item * B<input_escape_char> => I<str>

Specify character to escape value in field in input CSV, will be passed to Text::CSV_XS.

Defaults to C<\\> (backslash). Overrides C<--input-tsv> option.

=item * B<input_filename> => I<filename> (default: "-")

Input CSV file.

Use C<-> to read from stdin.

Encoding of input file is assumed to be UTF-8.

=item * B<input_header> => I<bool> (default: 1)

Specify whether input CSV has a header row.

By default, the first row of the input CSV will be assumed to contain field



( run in 1.953 second using v1.01-cache-2.11-cpan-64ef6c95b5d )