How to convert CSV to JSON in Perl?
Question
How to convert CSV to JSON in Perl?
How to Convert CSV to JSON in Perl
Converting CSV (Comma-Separated Values) data to JSON (JavaScript Object Notation) is a common task in text processing and data interchange. Perl excels at text manipulation, and with its core modules and rich ecosystem, you can easily handle CSV-to-JSON conversion.
This answer demonstrates a straightforward approach using only core Perl modules — no external CPAN dependencies — which makes your script portable and simple to run. We will:
- Parse CSV data using Perl's builtin
Text::ParseWords> module to handle quoted fields properly - Build Perl data structures representing the rows as hashes keyed by CSV headers
- Encode the resulting structure to JSON using Perl’s core
JSON::PP> module (available since Perl 5.14)
Key Perl Concepts Illustrated
@array(array sigil@) is used to handle list context for CSV fields%hash(hash sigil%) creates row-based key/value pairs from CSV headers and fields- TMTOWTDI ("There's More Than One Way To Do It") is reflected here as you could use a dedicated CSV module like
Text::CSV, butText::ParseWordssuffices for simple parsing - Scalar vs. list context: we parse line into an array, then map into a hash
Common Gotchas
- Improper CSV parsing can fail on quoted commas or embedded newlines. For complex CSV, prefer
Text::CSV. - Header count mismatch with data fields can cause errors; simple scripts assume consistent CSV files.
- JSON::PP is a pure-Perl JSON encoder included in Perl core >= 5.14, but on older versions you might need to install JSON::XS or JSON.
Runnable Perl Example
use strict;
use warnings;
use feature 'say';
use Text::ParseWords qw(parse_line);
use JSON::PP;
my $csv_data = <<'END_CSV';
name,age,city
Alice,30,"New York"
Bob,25,Los Angeles
Charlie,35,Chicago
END_CSV
# Split the CSV data into lines
my @lines = split /\n/, $csv_data;
# Parse header row to get field names
my $header_line = shift @lines;
my @headers = parse_line(',', 0, $header_line);
my @rows;
for my $line (@lines) {
next if $line =~ /^\s*$/; # skip empty lines
my @fields = parse_line(',', 0, $line);
# Pair up header => field into a hash for each row
my %row;
@row{@headers} = @fields;
push @rows, \%row;
}
# Convert the Perl data structure (arrayref of hashrefs) to JSON
my $json = JSON::PP->new->utf8->pretty->encode(\@rows);
say $json;
Output Explanation
The script parses a multiline CSV string with headers `name,age,city`. For each record, it constructs a hash mapping CSV columns to values, stores these hashes in an array, then encodes the array of hashes as nicely formatted JSON.
Running this will print:
[
{
"name" : "Alice",
"age" : "30",
"city" : "New York"
},
{
"name" : "Bob",
"age" : "25",
"city" : "Los Angeles"
},
{
"name" : "Charlie",
"age" : "35",
"city" : "Chicago"
}
]
Summary
Perl makes CSV to JSON conversion easy with core modules:
Text::ParseWords safely splits CSV fields even with quotes, while JSON::PP (included since Perl 5.14) encodes Perl data structures as JSON. For very complex CSV, Text::CSV CPAN module is recommended, but this lightweight script works great for common cases.
Remember the Perl sigils and context rules: arrays hold rows of fields, hashes map headers to values, and everything comes together elegantly to convert tabular CSV data into flexible JSON format.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 28ms
[
{
"city" : "New York",
"age" : "30",
"name" : "Alice"
},
{
"name" : "Bob",
"city" : "Los Angeles",
"age" : "25"
},
{
"age" : "35",
"city" : "Chicago",
"name" : "Charlie"
}
]
(empty)