By sorting, you can minimize the calls to mkdir, to open and to close. You can even sort such that the order is preserved in each file if so desired.
#!/usr/bin/perl -w
use strict;
#
# Run the script like:
# tail -n +2 car.csv | sort | ./foo.pl
#
# Or if you want to preserve order:
# tail -n +2 car.csv | sort -t, -k1,2 -s | ./foo.pl
#
use File::Path qw( mkpath );
my $out_dir = "/var/tmp/cars";
mkpath($out_dir, 0, 0777) or die;
my $last_make = '---';
my $last_model = '---';
my $fh;
while (<>) {
my ($make,$model) = split(/,/, $_, 4);
if ($make ne $last_make) {
mkdir("$out_dir/$make", 0777) or die;
$last_make = $make;
$last_model = '---';
}
if ($model ne $last_model) {
$fh = undef;
open($fh, '>', "$out_dir/$make/$model") or die;
$last_model = $model;
$fh = undef;
}
print $fh $_;
}