http://qs321.pair.com?node_id=521651

JFarr has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks. I'm still learning the nuiances of parsing in perl, so I ask your help. I have a file I'm reading in with the following data( there is more data than this one entry)
DsGccProxy.dll|AlarmForwarderServer.exe,AssetTracking.exe,CallerPositi +on.exe,ConferenceManager.exe,DirectionFinding.exe,EEAConfAccess.exd,E +EC_MARINE_BROADCAST.EXE,IncidentTracking.exe,MbEndpoinT.exe|YES
I've tried everything I can think of to parse this line. I need to be able to grab each field and the YES or NO at the end of the string. How in the heck do you parse this data? I've tried to do a
foreach my $t( @filename) { if( $t =~ m/\.exe/) { print $t,"\n"; } elsif( $t =~ m/\.dll/) { print $t , "\n"; } else { print $t, "\n"; } }
But this fails, it just prints the entire line entry.I've tried grepping it, but I'm not savy enough for this yet. Please help a struggling Perl-neophite. Thanks.

Replies are listed 'Best First'.
Re: Parsing a file with multiple delimeters
by diotalevi (Canon) on Jan 06, 2006 at 21:59 UTC

    It appears like that's a pipe delimited file with three columns, one of which happens to be internally delimited by commas. Use Text::CSV_XS.

    use Text::CSV_XS; my $csv = Text::CSV_XS->new( sep_char => '|' ); while ( <> ) { $csv->parse( $_ ); my ( $file, $file_list, $yes_no ) = $csv->fields; print "$_ $yes_no\n" for $file, split /,/, $file_list; }

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re: Parsing a file with multiple delimeters
by ptum (Priest) on Jan 06, 2006 at 21:59 UTC

    It sounds to me as though split() might do the trick for you. How 'bout this:

    my @tokens = split /\|/,$t; # I can't remember if | needs to be esc +aped or not

    Now $tokens[0] contains 'DsGccProxy.dll', $tokens[2] contains 'YES', and $tokens[1] contains all the executable names. If you want each of them, you could do a split on $tokens[1] using /,/ as the delimiter.

    Hope that gets you started. :)


    No good deed goes unpunished. -- (attributed to) Oscar Wilde
Re: Parsing a file with multiple delimeters
by jdporter (Paladin) on Jan 06, 2006 at 22:00 UTC

    Here's a simple way: (assumes reading lines from file F)

    while (<F>) { chomp; my( $dll_file, $exe_files, $do_it ) = split /\|/; my @exe_files = split /,/, $exe_files; }
    (I don't actually know what that third field means (the one that is 'YES' in your sample data))

    Update: Thanks to fishbot_v2 for pointing out my missing /\|/!

    We're building the house of the future together.
Re: Parsing a file with multiple delimeters
by saberworks (Curate) on Jan 06, 2006 at 21:59 UTC
    Use split to split on the pipe (|) delimiter.
    #!/usr/bin/perl -w use strict; my $line = 'DsGccProxy.dll|AlarmForwarderServer.exe,AssetTracking.exe, +CallerPosition.exe,ConferenceManager.exe,DirectionFinding.exe,EEAConf +Access.exd,EEC_MARINE_BROADCAST.EXE,IncidentTracking.exe,MbEndpoinT.e +xe|YES'; my ($file, $list_of_files, $bool) = split(/\|/, $line); warn "FILE: $file\n"; warn "LIST: $list_of_files\n"; warn "BOOL: $bool\n";
Re: Parsing a file with multiple delimeters
by ikegami (Patriarch) on Jan 06, 2006 at 21:59 UTC

    How about something like:

    while (<FILE>) { chomp; my ($dll, $users, $flag) = split(/\|/, $_); my @users = split(/,/, $users); ... }
Re: Parsing a file with multiple delimeters
by kulls (Hermit) on Jan 07, 2006 at 04:44 UTC
    I tried with simple understanding
    use strict; use warnings; my @filename=(raja.exe,rhs.dll,sd.sf); my $pattern='(\.exe) | (\.dll)'; foreach( @filename) { print $_ if( $_ =~ /$pattern/x ); }

    - kulls