Register
It is currently Tue Jul 22, 2014 5:01 pm

need some direction with a text replace script


All times are UTC - 6 hours


Post new topic Reply to topic  [ 3 posts ] 
Author Message
 PostPosted: Sun Apr 11, 2010 9:54 pm   

Joined: Sun Apr 11, 2010 9:36 pm
Posts: 3
Hey all,

I'm relatively new to bash (or any scripting language for that matter) and I'm having an issue that I can't seem to get past. Maybe someone here can point me in the right direction.
I'm trying to write a script that... well, it does a lot of things, but the problem I'm having is with two bits of functionality in particular.

1. read value_1 and value_2 from FILE_A (two per line, multiple lines)
2. append a line containing value_2 into FILE_B immediately after a line with value_1 is found in FILE_B.

That's probably confusing... I'll give an example.

FILE_A would be something like this:

Code:
172.27.1.107   hostname01.domain.corp
172.27.1.108   hostname02.domain.corp
172.27.1.131   hostname03.domain.corp


FILE_B would have a stanza like this:

Code:
<td class=default width="60%"><a href="#172_27_1_107">172.27.1.107</a></td>
<td class=default width="40%">Security warning(s) found</td></tr>


in this case, I'd like the script to turn the stanza above into the stanza below:

Code:
<td class=default width="30%"><a href="#172_27_1_107">172.27.1.107</a></td>
<td class=default width="30%"><a href="#172_27_1_107">hostname01.domain.corp</a></td>
<td class=default width="40%">Security warning(s) found</td></tr>



The changing of the "60%" value to the "30%" value is a no-brainer sed replace, and the append itself is fairly easy with sed as well, but I can't figure out how to have bash iterate through FILE_A while iterating through FILE_B at the same time. Can I do a nested while?

Any ideas?

Thanks.


Top
 Profile  
 PostPosted: Mon Apr 12, 2010 2:13 am   

Joined: Mon Mar 02, 2009 3:03 am
Posts: 532
Code:
#!/bin/bash

myFunc() {
   [ -f /proc/self/fd/7 ] || exec 7<FileA.txt
# this is more or less a while loop, but exits as soon as it matches
   if read -u7 lineA
   then if [ "${lineA%% *}" = "$2" ]
        then echo "$1"
             sed -r 's/(.*>)([0-9].{1,3}){1,3}[0-9]{1,3}(<.*)/\1'"${lineA##* }"'\3/' <<< "$1"
        else myFunc "$1"
        fi
   else exec 7<&-
   fi
}

while read lineB
do IP=$(sed -r 's/.*>(([0-9].{1,3}){1,3}[0-9]{1,3})<.*/\1/' <<<"$lineB")
   [[ $IP =~ ^([0-9].{1,3}){1,3}[0-9]{1,3}$ ]] && {
      myFunc "$(sed 's/[0-9]*%/30%/' <<< "$lineB")" "$IP"
   } || echo "$lineB"
done <FileB.txt


Top
 Profile  
 PostPosted: Mon Apr 12, 2010 11:04 am   

Joined: Sun Apr 11, 2010 9:36 pm
Posts: 3
Watael,

thanks for the quick reply.

That said, your reply is a bit over my head. :) I haven't even tested it yet because I'd really like to understand how it's doing what it's doing.... Mind if I ask some questions?

I understand that
Code:
[ -f /proc/self/fd/7 ] || exec 7<FileA.txt


will do
Code:
[ -f /proc/self/fd/7 ]

OR
Code:
exec 7<FileA.txt

matching the first condition will negate the rest of the line. But I'm a little confused about what those two choices actually mean. This is the first time I've heard of the /proc/self/fd/* files. In looking at my system, I have a 0, 1, 2, and 255 in that directory, but no 7. Would this be created at runtime? Mr. Google tells me that 0, 1, and 2 represent stdin, stdout and stderr, respectively, but doesn't have any info on 7 other than that 3-9 is an available range to use. My guess on this is that the script will check to see if /proc/self/fd/7 is a regular file, and when it finds that it doesn't exist (on my system), it will go to the second option. (Am I close?)
The second option is somewhat new to me as well, but I think it redirects FileA.txt to /proc/self/fd/7, yes?

The rest of the function:
Code:
   if read -u7 lineA
   then if [ "${lineA%% *}" = "$2" ]
        then echo "$1"
             sed -r 's/(.*>)([0-9].{1,3}){1,3}[0-9]{1,3}(<.*)/\1'"${lineA##* }"'\3/' <<< "$1"
        else myFunc "$1"
        fi
   else exec 7<&-
   fi


I kind of get, but I'm confused by the "lineA%%" and the "lineA##" What do the %% and ## represent?

In the while statement:
Code:
while read lineB
do IP=$(sed -r 's/.*>(([0-9].{1,3}){1,3}[0-9]{1,3})<.*/\1/' <<<"$lineB")
   [[ $IP =~ ^([0-9].{1,3}){1,3}[0-9]{1,3}$ ]] && {
      myFunc "$(sed 's/[0-9]*%/30%/' <<< "$lineB")" "$IP"
   } || echo "$lineB"
done <testreplace.html


What is the meaning of the "triple less-than" (i.e. <<<)?


Just trying to get an understanding of how the script works. Thanks for the help so far!


Mike


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP