Perl help...

AuntPeggy

Final Approach
PoA Supporter
Joined
May 23, 2006
Messages
8,480
Location
Oklahoma
Display Name

Display name:
Namaste
I know this must be easy in Perl using regular expressions, but I don't know Perl:

There are 2 files.
Arguments file
Overrides file
Structure in both files is: Name<tab>Value<tab>Type<tab>Comment

The first line of each file is a header.
Type is optional. If it starts with #, it is a comment, not a type.
Comments are optional.

For every line in the Overrides file, if there is a matching Name in the Arguments file, substitute the entire Overrides line in the Arguments file.
Except, if the Type is "skip" (no quotes) do not override the Arguments file.

If the Name does not appear in the Arguments file, append the Override line to the Arguments file.

For example, the following 2 files update the final file:
Original Arguments
Code:
Name<tab>Value<tab>Type<tab>Comment
arg1<tab>val1<tab>const<tab>#Dont change this
arg2<tab>val2<tab>#Dont change this either
arg3<tab>val3<tab>#Override this
arg4<tab>val4<tab>const<tab>Override this, too
arg5<tab>val5
Overrides
Code:
Name<tab>Value<tab>Type<tab>Comment
arg6<tab>val6<tab>#Append this
arg7<tab>val7
arg2<tab>val2a<tab>skip<tab>#Dont use this replacement
arg4<tab>val4a<tab>#Override with this
arg3<tab>val3a<tab>const<tab>#Replace with this
New Arguments
Code:
Name<tab>Value<tab>Type<tab>Comment
arg1<tab>val1<tab>const<tab>#Dont change this
arg2<tab>val2<tab>#Dont change this either
arg3<tab>val3a<tab>const<tab>#Replace with this
arg4<tab>val4a<tab>#Override with this
arg5<tab>val5
arg6<tab>val6<tab>#Append this
arg7<tab>val7
 
I'm not real sure what you're looking for Peg.

Do you want a perl program to do this or just an approach.

What I would use is a key-value hash for the arguments. Read the argument list first and then the overrides and hash will contain what you want.

For the parsing assuming the argument, value and type are made of alpha numerics
the regular expression would be something like: /(\w)\s(\w)\s(\w){0,1}\s*(#.*){0,1}/
the groups on a positive match would be the different fields.

Let me know if you want more details.

Joe

ps: I didn't check that regex either.
 
Last edited:
OK I'm bored and frustrated (my computer project is winning the battle). So attached is a little perl to do what I think you want. Joe
 

Attachments

I haven't programmed professionally in almost 5 years, but...

Code:
#!/usr/bin/perl -w

use strict;

my %args;

foreach my $file (@files) {  # this assumes you have the files in order 0,1
  process($file, \%args);
}

# %args should now be the "appropriate" file

open(OUTPUT, "file") or die "Unable to open file: $!\n";

print OUTPUT $args{'firstline'};
print OUTPUT map { join("\t", @args{$_} ) } grep { /!firstline/ } sort keys %args;

close OUTPUT;

exit;

sub process ($$) {

  my $file = shift;
  my $argsref = shift;

  open(INPUT, "$file") or die "Unable to open file: $!\n";

  my $firstline = 0;

  while(<INPUT>) {
    next if /skip/;
    $$argsref{'firstline'} = $_ if $firstline = 0;
 
    my @args = split(/\t/);
    @$argsref{$args[0]} = @args[1..$#args];

    $firstline++; # needless after 0; I could do an if block, I'm lazy
  }
}
 
Last edited:
Peggy,

Did either of those code snippets help at all?

Joe

Sorry to get back to you so late. Had to take a couple of days off for someone to sue me (postponement) and eye exams (4 hours).

Andrew's snippet results in some syntax errors.
Code:
D:\Test Tools\overrides>perl andrew.pl
Scalar value @args{$_} better written as $args{$_} at andrew.pl line 16.
Found = in conditional, should be == at andrew.pl line 33.
main::process() called too early to check prototype at andrew.pl line 8.
Global symbol "@files" requires explicit package name at andrew.pl line 7.
Execution of andrew.pl aborted due to compilation errors.

Yours results in:
(1 time) name from original file and from overrides file both included in final.
(3 times) name from original file, not in overrides, not included in final.
(1 time) name from original file and in overrides, not included in final.
(4 times) name not in original file, in overrides, not included in final.

I am attaching a word document with side-by-side comparisons of the actual files used. (altered for confidentiality)

Bold indicates success.
Italics indicates missing.
Underline indicates name of missing.
Overstrike indicates should be eliminated.
 

Attachments

Try this one. My mistake was assuming the values were alphanumerics so the special characters caused the problem of missing lines. I'm not quite sure how duplicates were possible but there were none in this run.

Joe
 

Attachments

:blowingkisses:Thanks. This one seems to work fine. You've just saved me a ton of work.
 
:blowingkisses:Thanks. This one seems to work fine. You've just saved me a ton of work.
You're welcome. Glad it worked for you.

Perl is one of those languages that takes a lot of time to learn but once you get it it makes things like this easy.

Joe
 
:blowingkisses:Thanks. This one seems to work fine. You've just saved me a ton of work.

Like I said, 5 years. I had some stupid little errors in it; of course it worked before I wrote "use strict".

Stupid. Sorry Peggy.

-ars
 
Back
Top