Skip to content

Instantly share code, notes, and snippets.

@RomanHargrave
Created February 25, 2020 04:13
Show Gist options
  • Save RomanHargrave/f3166f88af3d6b65c68ef844c7f2f44e to your computer and use it in GitHub Desktop.
Save RomanHargrave/f3166f88af3d6b65c68ef844c7f2f44e to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
use warnings;
use strict;
use Text::CSV;
use Getopt::Long;
use Data::Dumper;
my $in_file = '-';
my $out_file = '-';
my $field_sep = ':';
my $csv_sep = ',';
my $csv_quote = '"';
my $csv_escape = '"';
my $expression = undef;
my $allow_malformed = 0;
my $suppress_header = 0;
my @fields = ();
my %appends = ();
GetOptions(
'in=s' => \$in_file,
'out=s' => \$out_file,
'field=s' => \@fields,
'fs=s' => \$field_sep,
'expr=s' => \$expression,
'csv-sep=s' => \$csv_sep,
'csv-quote=s' => \$csv_quote,
'csv-escape=s' => \$csv_escape,
'append=s' => \%appends,
'allow-malformed' => \$allow_malformed,
'suppress-header' => \$suppress_header,
);
@fields = ('username', 'password') unless @fields;
# this is used for split(), and should not account for appended fields
my $field_count = $#fields + 1;
my @append_vals = ();
if (%appends) {
@fields = (@fields, keys %appends);
@append_vals = values %appends;
}
open my $input, "<$in_file";
open my $output, ">$out_file";
my $csv = Text::CSV->new({
sep_char => $csv_sep,
quote_char => $csv_quote,
escape_char => $csv_escape,
}) or die 'Failed to create Text::CSV: ' . Text::CSV->error_diag();
# write header row
$csv->say($output, \@fields) unless $suppress_header;
sub decompose_sep {
my ($line, $dest) = @_;
@$dest = split(/$field_sep/, $line, $field_count);
}
sub decompose_expr {
my ($line, $dest) = @_;
@$dest = $line =~ /$expression/;
}
my $decompose = undef;
if ($expression) {
$decompose = \&decompose_expr;
} else {
$decompose = \&decompose_sep;
}
my @buf = ();
while (<$input>) {
chomp;
$_ =~ tr/\r//d;
&$decompose($_, \@buf);
next unless (scalar @buf) == $field_count || $allow_malformed;
# append empty strings if size is less than expected
push @buf, '' while (scalar @buf) < ($field_count);
@buf = (@buf, @append_vals);
$csv->say($output, \@buf);
}
close $input;
close $output;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment