regex - Replace all text within two strings on different lines using Perl -
i web developer. agency work uses dreamweaver templating/library item features. library items come in handy updating nav bar or piece of content thats same on every page. work static html of time. change menu item, use dreamweaver library item, update item once, press update, , changes across every html page in project.
make perl script can run command line instead of opening gui, faster.
so example, lets have menu coded this:
<!--menuitems--> <li><a href="products.html">products</a></li> <li><a href="about_us.html">about us</a></li> <li><a href="commercial.html">commercial</a></li> <li><a href="contact.html">contact</a></li> <!--menuend-->
i store the li items code in own file: nav.lbi:
<li><a href="products.html">products</a></li> <li><a href="about_us.html">about us</a></li> <li><a href="commercial.html">commercial</a></li> <li><a href="contact.html">contact</a></li>
the perl script needs replace in each file scans text between <!--menuitems-->
, <!--menuend-->
contents of nav.lbi.
i going first try in sed, sed tailored line line stuff. have had success using sed insert entire text file somewhere in file, bit different. perl know should able replace text between every occurance of <!---menuitems-->
, <!--menuend-->
contents of nav.lbi, though spans multiple lines.
if need add <!--menuitems-->
, <!--menuend-->
tags nav.lbi file, since doing search , replace, if make easier, fine too. can update navigation bar across multiple html files without needing touch dreamweaver.
1 last thing note there multiple occurances of <!--menuitems-->
, closing <!--menuend-->
because navigation in header identical navigation in footer, need update file recursively.
the following builds upon dov grobgelds answer, has additional functionality added asked in comments answer. precisely runs multi line find , replace on html files in directory , overwrites original file:
#!/usr/bin/perl use strict; use warnings; sub slurp { $fn = shift; open(in,$fn); return join('',<in>); } @files = grep ( -f ,<*.html>); $file (@files) { print "$file\n"; $_ = slurp("$file"); $new_menu_items = slurp("nav.lbi"); open $output_file, '>', "$file"; s/<!--menuitems-->(.*)<!--menuend-->/$new_menu_items/s; print $output_file $_; }
explanation:
first question how print output file, rather terminal. (refer dov grobgelds answer compare original code)
1.specifiy output file be:
open $output_file, '>', 'output.html';
then print output file:
print;
- original answer
becomes:
print $output_file $_;
now make script run on html files in directory, need turn script more dynamic. need store .html files in vars in array, , iterate through array, storing each .html var, running slurp/regex code on each file.
first declare variable holds html files , populate .html files in current directory:
my @files = grep ( -f ,<*.html>);
the rest of magic happens wrapping original slurp , regex code in loop:
#for each file in files array, file stored via $file: $file (@files) { #unecessary put prints out file filename loop working on: print "$file\n"; #default var becomes current file contents: $_ = slurp("$file"); #this part isn't dynamic, same each loop, there might better #place put this: $new_menu_items = slurp("nav.lbi"); #makes output filename same input: open $output_file, '>', "$file"; #runs regex replace on file contents of orig file s/<!--menuitems-->(.*)<!--menuend-->/$new_menu_items/s; #saves contents out original file #(overwriting original data loaded after running regex on it:) print $output_file $_; }
lets closing tag not unique, in dreamweaver template, can add ? (.*) match first occurance, instead of last:
s/<!--menuitems-->(.*?)<!--libraryitemend-->/$new_menu_items/s;
Comments
Post a Comment