Bash - While Loop reading from two lists simultaneously - nested while loop
Hi,
I use while loops to make configuration changes on network devices all the time, so I am pretty familiar with while loops, but I can't seem to get this to work. I need to make configuration changes in separate parts of the command tree on the multiple devices. This basically requires a while loop to read from two separate lists of commands and echo alternating output from those lists. I usually use expect, but in this case all I need is to echo some command output to a file and then paste it into the terminal. Here is an example: The command output starts like this: subnet 71.1.24.0/21 name dhcp03 range 71.1.24.2 71.1.31.254 subnet 71.50.128.0/21 name dhcp02 range 71.50.128.2 71.50.135.254 subnet 184.3.144.0/21 name dhcp01 range 184.3.144.2 184.3.151.254 I need to add "threshold falling 100 log" to the end of the lines that start with "range". However, in order to get to that point, you have to enter the lines that start with "subnet" first. So, I created two lists, similar to the following: subnet 71.1.24.0/21 name dhcp03 subnet 71.50.128.0/21 name dhcp02 subnet 184.3.144.0/21 name dhcp01 range 71.1.24.2 71.1.31.254 range 71.50.128.2 71.50.135.254 range 184.3.144.2 184.3.151.254 I would think I would need to crete a nested while loop to do this, but I can't get it to work at all. Here is what I have so far: #!/bin/bash # dhcpbugchange.sh outer=1 # Set outer loop counter. # Beginning of outer loop. cat subnets.txt | while read subnet do echo "$subnet" inner=1 # Reset inner loop counter. # Beginning of inner loop. cat ranges.txt | while read range do echo "$range threshold falling 100 log" let "inner+=1" # Increment inner loop counter. done # End of inner loop. let "outer+=1" # Increment outer loop counter. echo # Space between output blocks in pass of outer loop. done # End of outer loop. exit 0 I chmod +x and chmod 777 and this is what I get: bash-3.00$ ./dhcpbugchanges.sh : bad interpreter: No such file or directory bash-3.00$ what am I doing wrong? |
For the collation task, try paste -d'\n' file1.txt file2.txt. Adding the string to the "range" lines can be done a few different ways.
Code:
paste -d'\n' file1.txt file2.txt | sed '/^range /s/$/ threshold falling 100 log/' Code:
sed 's/$/ threshold falling 100 log/' file2.txt | paste -d'\n' file1.txt - |
Is your bash in /bin? While it is in openSUSE and OS X, other distributions put it in /usr/bin. What is:
Code:
$ which bash |
Quote:
Kevin Barry |
Quote:
Code:
allen@tornado:~$ paste -d'\n' subnets.txt ranges.txt | sed '/^range /s/$/ threshold falling 100 log/' Code:
allen@tornado:~$ sed 's/$/ threshold falling 100 log/' ranges.txt | paste -d'\n' subnets.txt - 1.) paste -d'\n' subnets.txt ranges.txt | sed '/^range /s/$/ threshold falling 100 log/' Says: "Use the paste command, using a line feed (\n) as a delimiter for the files "subnets.txt" and "ranges.txt". Pipe the output to sed. With sed, anything starting (hence the ^) with the word "range" needs to have something added to the end (hence the $) of the string (hence the usage of the s option). That "something" is "threshold falling 100 log". 2.) sed 's/$/ threshold falling 100 log/' ranges.txt | paste -d'\n' subnets.txt - Says: Use sed to add something to the end (hence the $) of the string (hence the usage of the s option) in the file "ranges.txt". That something is "threshold falling 100 log". Pipe the output to the paste command, using a new line feed (\n) as the delimiter (hence the -d option) for the file subnets.txt. However, this is where it gets fuzzy. I'm assuming that the - tells sed to somehow start with the output of the subnets.txt file first? But, I tried removing the hyphen to see what happened and it didn't print the ranges.txt output at all? Thanks in advance! |
Quote:
This is a good sed reference: http://www.grymoire.com/Unix/Sed.html Here is a decent regular expression reference: http://www.zytrax.com/tech/web/regex.htm Kevin Barry |
While it is rarely useful, you can, technically, read multiple files in a Bash loop simultanously, if you use file descriptors. Here are two examples:
Code:
#!/bin/bash (As Reuti pointed out below, I had b0rked the descriptor closing above. Fixed; thanks, Reuti!) |
Quote:
Code:
exec 11<&- 12<&- 13<&- |
Read multiple files in a Bash loop simultanously--the final solution
Code:
#!/bin/bash |
Quote:
Code:
destroy_fd() |
Quote:
and so: Code:
while eval "${Read[@]:0:${#Read[@]}-1}" |
Quote:
|
All times are GMT -5. The time now is 03:05 PM. |