Forum: Cfengine Help
Subject: Re: Editing only the first line in a file
Author: sauer
Link to topic: https://cfengine.com/forum/read.php?3,21478,21530#msg-21530

Frans Lawaetz Wrote:
-------------------------------------------------------
> There is an "occurrences" option to line edit
> promises.  
> cfengine_stdlib.cf has the following:
> 
> body replace_with value(x)
> {
> replace_value => "$(x)";
> occurrences => "all";
> }
> 
> Try setting it to just "first".

I don't want the first occurance, though - I want to replace it only if it's on 
the first line.  If, for some reason, someone includes that string later on in 
the file (perhaps in a print statement or some in-line documentation), I want 
to leave it alone.

The solution I identified does work, albeit slowly (ok,checking 3141 files is 
just gonna be slower than setting permissions; it generally takes about 15-20 
minutes).  Here's the solution I'm ultimately using:


bundle edit_line perl_interpreter {
replace_patterns:
  "#!(?!$(perl_path)\s.*U).*perl(?:\s.*)?"
    replace_with  => value( "#!$(perl_path) -U" ),
    select_region => interpreter_line;
}
body select_region interpreter_line {
  #select_start => "#!/\S*perl.*";
  select_start => ".*";
  select_end   => "(?!#!).*";
  include_start_delimiter => "true";
  include_end_delimiter   => "false";
}


I changed the select_start to be ".*" in order to suppress the "unable to 
sleect a range" messages I get in all of the .pl files which do not have a perl 
interpreter at the top, and then changed the replace pattern to use a 
zero-width negative lookahead verifying that I don't have the interpreter I 
want followed by a capital U (so, for example, /usr/bin/perl -wU is also ok), 
and also verifying that I do have a command which has perl followed by either 
whitespace or nothing.  I suppose that, for maximum flexibility, I should 
expand the regex to match any arguments which don't conflict with -U (ie, -T) 
and carry those forward.  But I'm not going to do that.:)

I'm not entirely sure how setting the include_end_delimiter to false is working 
in the case where the first line doesn't have a #!, since the start and end 
would potentially both match the same first line - but I don't much care at 
this point because I'm not going to edit those files.

On a related note, editing "/path/to/files/.*\.cgi" dissapointingly does not 
work; it only edits the last file an "ls *.cgi" would return. :/

_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to