# perldoc > Text::CSV

---
type: CommandReference
command: Text::CSV
mode: perldoc
section: 
source: perldoc
---

## Quick Reference

- `csv(in => "file.csv")` — read whole file as array of arrays
- `csv(in => "file.csv", headers => "auto")` — read as array of hashes
- `csv(in => $aoa, out => "file.csv", sep_char => ";")` — write array of arrays to CSV
- `csv(in => "data.csv", filter => { code => sub { $_ % 2 } })` — filter rows
- `$csv = Text::CSV->new({ binary => 1, auto_diag => 1 })` — create object with strict parsing
- `$csv->getline($fh)` — parse one line from filehandle
- `$csv->print($fh, $colref)` — write one row
- `$csv->parse($line)` — parse a string

## Name

**Text::CSV** — comma-separated values manipulator (using XS or PurePerl)

## Synopsis

perl
# Functional interface
use Text::CSV qw( csv );

my $aoa = csv(in => "data.csv");
my $aoh = csv(in => "data.csv", headers => "auto");
csv(in => $aoa, out => "file.csv", sep_char => ";");

# Object interface
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
open my $fh, "<:encoding(utf8)", "test.csv" or die "test.csv: $!";
while (my $row = $csv->getline($fh)) {
    push @rows, $row;
}
close $fh;

open $fh, ">:encoding(utf8)", "new.csv" or die "new.csv: $!";
$csv->say($fh, $_) for @rows;
close $fh or die "new.csv: $!";
## Options

Options for `new()`:

- `eol` — end-of-line string for output or record separator for parsing. Default: `undef` (accepts `\n`, `\r`, `\r\n`)
- `sep_char` — field separator character, default `,`
- `sep` — multi-byte separator (up to 8 bytes), overrides `sep_char`
- `quote_char` — field quoting character, default `"`
- `quote` — multi-byte quote (up to 8 bytes), overrides `quote_char`
- `escape_char` — escape character inside quoted fields, default `"`
- `binary` — allow binary data including newlines inside quoted fields (recommended)
- `decode_utf8` — auto-decode fields to UTF-8 (default true)
- `auto_diag` — automatically warn/die on errors (1=warn, 2=die)
- `diag_verbose` — add record number to diagnostic output
- `blank_is_undef` — treat unquoted empty fields as `undef` (for database NULL)
- `empty_is_undef` — treat all empty fields as `undef`
- `allow_whitespace` — strip whitespace around separators
- `allow_loose_quotes` — allow quotes inside unquoted fields
- `allow_loose_escapes` — allow escape on non-special characters
- `always_quote` — quote all defined fields on output
- `quote_space` — quote fields containing spaces (default true)
- `quote_empty` — quote empty defined fields
- `quote_binary` — quote fields with bytes >= 0x7F (default true)
- `escape_null` — escape `\0` bytes (default true, but false for `csv()` function)
- `keep_meta_info` — store quoting/binary flags for retrieved fields
- `strict` — enforce consistent field count per row
- `skip_empty_rows` — skip empty lines during parsing
- `formula` / `formula_handling` — action on fields starting with `=`: `none`, `die`, `croak`, `diag`, `empty`, `undef`, or a callback
- `undef_str` — output string for `undef` fields
- `comment_str` — string indicating comment lines (skipped)
- `verbatim` — treat newlines as ordinary characters (for non-standard line endings)
- `types` — array of column type references (`IV`, `NV`, `PV`)
- `callbacks` — hashref of callbacks (see below)

## Examples

**Reading with object and filtering:**

perl
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
open my $fh, "<:encoding(utf8)", "test.csv" or die "test.csv: $!";
while (my $row = $csv->getline($fh)) {
    $row->[2] =~ m/pattern/ or next;
    push @rows, $row;
}
close $fh;
**Using `csv()` function with BOM detection:**

perl
my $aoh = csv(in => "file.csv", detect_bom => 1, headers => "auto");
**Writing with custom separator and quoting:**

perl
csv(in => $aoa, out => "out.csv", sep_char => ";", always_quote => 1);
**Using `bind_columns` for performance:**

perl
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
open my $fh, "<", "data.csv" or die;
my ($code, $name, $price);
$csv->bind_columns(\$code, \$name, \$price);
while ($csv->getline($fh)) {
    print "Price of $name is $price\n";
}
## See Also

- [Text::CSV_XS](https://metacpan.org/pod/Text::CSV_XS)
- [Text::CSV_PP](https://metacpan.org/pod/Text::CSV_PP)
- [Text::CSV::Encoded](https://metacpan.org/pod/Text::CSV::Encoded)

## Exit Codes / Diagnostics

Error codes (first three letters indicate category: `INI`, `ECR`, `EOF`, `EIQ`, `EIF`, `ECB`, `EHR`):

- `1001` — `sep_char` equals `quote_char` or `escape_char`
- `1002` — `allow_whitespace` with `quote_char`/`escape_char` as space/tab
- `1003` — `\r` or `\n` in `sep_char`/`quote_char`/`escape_char`
- `1004` — `callbacks` not `undef` or hashref
- `1005`–`1008` — EOL/SEP/QUOTE too long or undefined
- `1010` — header is empty
- `1011` — header contains more than one valid separator
- `1012` — header contains empty field
- `1013` — header contains non-unique fields
- `1014` — header called on undefined stream
- `1500` — invalid arguments
- `1501`–`1503` — invalid `key`/`value` attribute
- `2010`–`2014` — carriage return / end-of-file / fragment / strict field count errors
- `2021`–`2027` — errors inside quoted fields (newline, CR, binary, unterminated, etc.)
- `2030`–`2037` — errors inside unquoted fields
- `2110` — binary character in combine with binary off
- `2200` — print to IO failed
- `3001`–`3010` — hashref / column / bind errors