http://www.perlmonks.org?node_id=979627


in reply to parse a line with varied number of fields

As long as you have a constant number of fields and the only field that can contain spaces is your filename one, the problem can be solved using the third argument to split combined with reverse.

knoppix@Microknoppix:~$ perl -Mstrict -Mwarnings -E ' > my @lines = ( > q{1 2 3 4 5 6 7 8 filename 10 11 12 13 14 15 16 17 18}, > q{1 2 3 4 5 6 7 8 file name 10 11 12 13 14 15 16 17 18}, > q{1 2 3 4 5 6 7 8 new file name 10 11 12 13 14 15 16 17 18}, > ); > > foreach my $line ( @lines ) > { > my @flds = split m{\s+}, $line, 9; > @flds = split m{\s+}, reverse( $flds[ -1 ] ), 10; > my $filename = reverse $flds[ -1 ]; > say qq{>$filename<}; > }' >filename< >file name< >new file name< knoppix@Microknoppix:~$

I hope this is helpful.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re^2: parse a line with varied number of fields
by vt220 (Scribe) on Jul 03, 2012 at 19:03 UTC
    At first glance this seemed unnecessarily complicated but then I thought, "No, it couldn't be doing that!" So I tried...
    #!/usr/bin/perl use Modern::Perl; my @lines = ( q{1 2 3 4 5 6 7 8 filename 10 11 12 13 14 15 16 17 18}, q{1 2 3 4 5 6 7 8 file name 10 11 12 13 14 15 16 17 18}, q{1 2 3 4 5 6 7 8 new file name 10 11 12 13 14 15 16 17 18}, ); foreach my $line ( @lines ) { my @flds = split m{\s+}, $line, 9; @flds = split m{\s+}, reverse( $flds[ -1 ] ), 10; my $filename = reverse $flds[ -1 ]; say qq{>$filename<}; } foreach my $line ( @lines ) { my @flds = split(' ', $line); my $filename = join(' ', @flds[8 .. $#flds - 9]); say qq{<$filename>}; }
    Yes, yours preserves multiple spaces in the file name. Thanks for the enlightenment JohnGG!
      preserves multiple spaces in the file name

      In case others are puzzled let's share the enlightenment and explain what is going on. The reason spaces are preserved is that the file name field is never actually split. First, the line is broken into nine fields.

      1 2 3 4 5 6 7 8 file name 10 11 12 13 14 15 16 17 18 ^ ^ ^ ^ ^ ^ ^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

      Then the last field from the first split operation is reversed and broken into 10 fields.

      81 71 61 51 41 31 21 11 01 eman elif ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^

      Finally the last field from the second split operation is reversed to obtain the file name.

      file name

      Note that spaces in the file name will be preserved but if the file name has leading and/or trailing spaces the method fails as they will be lost.

      Cheers,

      JohnGG

Re^2: parse a line with varied number of fields
by raggmopp (Novice) on Jul 03, 2012 at 13:19 UTC

    Thanks John. I have been thinking about reverse. Hoping to see if there is something better.