[SOLVED] bash script to dynamically edit an html file
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
So it did match the hostname to the ip (which is awesome!), but it also seemed to duplicate every other line, and input zeroes for every second character on most other lines. So how is this script finding the ip? Is it using the regex in:
Code:
{match($2,/[0-9]+/,pc);gsub(pc[0],pc[0]/2)}
or is it pulling it from a specific field?
Oh, and for what it's worth, the second script does the same as the first, except it doesn't match the hostname to the ip. It duplicates every line and inputs the extra zeroes.
while read ip hostname;do
line='<td class=default width="60%"><a href="#'${ip//./_}'">'
ip=${ip//./\\.} # Escape the dots: 172\.27\.1\.107
sed -i "/$line/{ s/60%/30%/; h; s/$ip/$hostname/; x; G }" nessus.html
done < hostnames.txt
The above method runs sed once for each ip/hostname. If there are a large number of ip/hostnames it would be more efficient to create a script of sed commands so that all the editing of the file can be done with just a single run of sed.
Code:
> sedscript # Start with an empty sedscript file
while read ip hostname;do
line='<td class=default width="60%"><a href="#'${ip//./_}'">'
ip=${ip//./\\.} # Escape the dots: 172\.27\.1\.107
echo "/$line/{ s/60%/30%/; h; s/$ip/$hostname/; x; G }" >> sedscript
done < hostnames.txt
sed -f sedscript nessus.html > newnessus.html
I will try and break it down for you, oh and sorry about the duplication of the other lines <my bad> will fix that too
BEGIN{FS="[\\||>*<*]"} - Set the delimeters to be used, in this case \\| is the pipe for ipsandhost and >*<* is for sedtest
ARGV[1] == FILENAME{_[$1]=$2} - while in file ipsandhost create an array where index is ip and value is host name
ARGV[2] == FILENAME{ - while in second file sedtest
if($5 in _) - if after splitting line the fifth field (ip address) is one of the indexes in array _
{match($2,/[0-9]+/,pc); - match is a function which looks for the regex /[0-9]+/ (this is one or more numbers) in string represented by field 2 and store in array pc
gsub(pc[0],pc[0]/2) - for the whole line (represented by $0) change all occurrences equal equal to value stored in pc[0] (which was 60 in example) with pc[0]/2 (ie 30);
print $0"\n"gensub($5,_[$5],2)} - print the original line ($0) plus the newline character ("\n") on newline print $0 but replace the fifth filed string (represents the ip address) with the value stored in array equivalent to that address (_[$5]) but only replace second occurrence (2). reason for last part is because the searched for string has dots in it (ie the ones separating the ip address) it also is matching any character between numbers, hence if you make it global it will also replace 172_27_1_58 as numbers are the same and dot "." is matching the underscore "_"
// extra stuff I should have put in. you will notice that the print above is now in the 'if'
else print} - this will now print the line as is if it does not require a change
${ip//./\\.} is bash parameter expansion (sometimes called 'parameter substitution' or 'variable substitution').
It's similar to the sed s/ / / command but it uses filename globbing patterns, not regular expressions.
Code:
var="some dogs are doggedly dogmatic"
echo ${var/dog/cat} # replace first
some cats are doggedly dogmatic
echo ${var//dog/cat} # replace all
some cats are catgedly catmatic
echo ${var/*d??/cat} # globbing pattern
catmatic
${ip//./\\.} is bash parameter expansion (sometimes called 'parameter substitution' or 'variable substitution').
It's similar to the sed s/ / / command but it uses filename globbing patterns, not regular expressions.
Code:
var="some dogs are doggedly dogmatic"
echo ${var/dog/cat} # replace first
some cats are doggedly dogmatic
echo ${var//dog/cat} # replace all
some cats are catgedly catmatic
echo ${var/*d??/cat} # globbing pattern
catmatic
I didn't even know this existed... Thanks for the education!
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.