in reply to Need to build attribute parser

It might be stupid, but why not do a diff?

Otherwise I guess this would work:

#!/bin/perl -w use strict; my( $file1, $file2)= @ARGV; my %v1= parse_att( $file1); my %v2= parse_att( $file2); $\="\n"; my @new= grep { !$v2{$_} } keys %v1; my @deleted= grep { !$v1{$_} } keys %v2; print "new: ", join "\n ", @new; print "deleted: ", join "\n ", @deleted; sub parse_att { my $file= shift; my %atts; my $field=''; open( FILE, "<$file") or die "I'd better tell you that the open su +cceded or I'll get --'ed into oblivion, I'll even report why I failed +: $!"; while( <FILE>) { chomp; my $val; if( m/^\s*-([\w-]+) \s*:\s*([^,]*),?$/) { ($field, $val)= ($1, $2); } elsif( m/^\s*([^,]*),?$/) { $val= $1; } else { die "uh-oh, looks like this line has a problem: $_"; } # why bother with clever data structures $atts{"$field $val"}=1; } return %atts; }

Replies are listed 'Best First'.
RE: Re: Need to build attribute parser
by Lord Rau (Novice) on Sep 28, 2000 at 23:59 UTC
    OK... So I tried the above and that was great but in my rush to post. I didn't accurately represent the sample data. So the script is dying on certain unparsable lines. (See below.)

    Any advice? Lines like this also exist!
    -frame-print-settings-path : !{dazel-install-directory}!/lib/fm_pr +int_settings.doc -font-directories : !{dazel-install-directory}!/lib/FONTS +/Soft_Horizons -ps-init-directories : !{dazel-install-directory}!/lib/PS -footer-text-default : Printed by DAZEL, Page !{page-number}!, !{started-printing-time}! -header-footer-font : Helvetica-Bold -header-footer-font-size : 12 -ps-prologue-file : ps_prologue.psc, hp8500dn.ps -physical-device-type : ps-printer -output-document-format-default: ps -output-bin-xlate : {face-down, 1}, {top, 1}, {face-up, 2}, {left, 2} -input-trays-xlate : {tray1, 0}, {tray2, 2}, {tray3, 3}, {tray4, 4}, {large-capacity, 4} -ps-printer-echoes-eof : true

      The problem is probably that some lines include commas, so the [^,]* stops at the first comma instead of the last one

      so you need to replace:

      if( m/^\s*-([\w-]+) \s*:\s*([^,]*),?$/) { ($field, $val)= ($1, $2); } elsif( m/^\s*([^,]*),?$/) { $val= $1; }

      by

      if( m/^\s*-([\w-]+) \s*:\s*(.*)$/) { ($field, $val)= ($1, $2); } elsif( m/^\s*(.*)?$/) { $val= $1; } $val=~s/,$//;