Parsing text files in BASH!
Please help!
I'm trying to write a script to list all open ports in the MINIUNPND chain in iptables and use the procotol, port and destination ip to open ports on another router using upnpc. Here is the output of iptables -L MINIUPNPD Code:
>iptables -L MINIUPNPD Code:
#!/bin/bash Code:
>cat tmp.txt Code:
upnpc -r -a $destiation $portnumber $protocol i have tryied using various scripts based around this Code:
index=0 Code:
index=0 I thought it would simply be a loop reading each line and passing the fields in variables, executing upnpc commands i need then moving to the next line of the file until it reached the EOF Someone please help as i have spent 2 days trying to get this to work. Thanks in advance guys |
Code:
MYDEST[$index]=$(awk -v t="$line" '{print $5}') I don't have time to test it out now, but I'd probably get awk to print all three fields at once, and use that to set an intermediate array. Then use that array to set your final array variables. Something like this: Code:
|
Assuming you want to keep all of the work up to the point of extracting the data to a file:
Code:
while read a b c; do echo upnpc -r -a $a $b $c; done < <( cat tmp.txt ) --- rod. EDIT: missed some of the requirements, see below |
Okay, couldn't let it go:
Code:
while read a b c; do Output sample: Code:
upnpc -r -a 192.168.3.124 19955 tcp |
How about:
Code:
iptables -L MINIUPNPD | awk 'NR > 2{sub(/.*:/,"",$7),cmd = "upnpc -r -a "$5" "$7" "$6;print | cmd}' |
Wow Thank you theNbomr (rod) You are a star!
That script works lovely! Any chance you can please explain HOW it works? I understand most if it except the syntax of "(awk 'NF == 7 { print $5, $6, $7 }' /tmp/LQUrbanPykey.iptables)". Its the syntax of operators i get confused with in bash! Now all i have to do is get this script run by cron at regular intervals or whenever the MINIPNPD chain of iptables changes! Oh and grail your script cause me to get a syntax error [CODE] iptables -L | awk 'NR > 2{sub(/.*:/,"",$7),cmd = "upnpc -r -a "$5" "$7" "$6;print | cmd}' awk: NR > 2{sub(/.*:/,"",$7),cmd = "upnpc -r -a "$5" "$7" "$6;print | cmd} awk: ^ syntax error [CODE] |
I think i understand now! NF==7 states it only looks at lines with EXACTLY 7 fields yes?
Just the syntax of the [code]c=$(echo $c | cut -d: -f2)[code] I have to research! Oh and regular checking the MINIUPNP chain of iptables Once again THANKS! |
Quote:
grails effort trumps mine, once you get it working; doesn't use a temp file. The awk part does only look at records with exactly 7 fields. --- rod. PS [CODE]how to use code tags[/CODE] |
Happy Now
It would take me a degree in BASH to work out HOW Grails script works! Your script is more at my level, ONCE i get into my head how the syntax of bash works a bit more. It all seemed so easy laid out on paper in pseudo code!
Anyways here is my completed script, i have added some extra variables to avoid upnpc failing to discover the remote router and to set the destination to the local IP of the local ClearOS gateway Code:
#!/bin/bash |
Well mine was a simple typo :(
The comma should be a semi colon, try: Code:
iptables -L MINIUPNPD | awk 'NR > 2{sub(/.*:/,"",$7);cmd = "upnpc -r -a "$5" "$7" "$6;print | cmd}' 1. iptables -L MINIUPNPD | awk - redirect the output of iptables command into awk 2. NR > 2 - this is equivalent to your sed of removing the first 2 lines, mine just ignores them. (PS should you still only be wanting to look at lines with 7 arguments, you can simply add - && NF == 7 before curly brace) 3. sub(/.*:/,"",$7) - remove everything up until the full colon from the last field (eg. dpt:19955 becomes 19955) 4. cmd = "upnpc -r -a "$5" "$7" "$6 - this is setting the variable cmd to a string representation of what you wish to execute (using your first line of input from iptables in post #1 it would be - cmd = "upnpc -r -a 192.168.3.124 19955 tcp" ) 5. print | cmd - use the command in the shell Let me know if you need anymore information :) |
AH! i understand! AWK is performing all the operations within the ' ' delimiters. so your script is a lot less processor use since it only calls 3 "programs" AWK, IPTABLES and UPNPC whereas mine performs alot more operations!
Only problem now is working out if i can use incron or inotify to monitor the changes to the MINIUPNPD chain and if it notices a change, run the upnpforwarder script! only thing i can think so far, and i have only just started thinkling about it, would be altering MINIUPNPD slightly to "touch" a file when it adds rules to the MNINIUPNPD chain. incron or inotify can then look for this "touch"ed file. Any ideas would be much appreciated! |
Sorry ... but I do not know much about iptables and nothing about MINIUPNPD. It may pay to raise another question as the gist of this one has been answered.
|
Code:
b=$(echo $b | cut -d: -f2) Code:
b=${b#*:} Code:
An alternate technique would be to alter awk's field separator to account for both spaces and colons, then you can output the field you want directly and not have to worry about splitting it later. Code:
done < <(awk -F "[[:blank:]:]+" 'NR > 2 { print $6, $8 }' tmp.txt) This should break the colon-ated part into two separate fields. Also, my personal preference is to use NR > 2 to simply skip the first two lines, instead of testing the number of fields on every line. But if you do decide to continue using NF instead, don't forget that NF == 8 now. How about using the awk command to directly filter the output of iptables instead, so that the temp file only contains the fields you want? Code:
iptables -L MINIUPNPD | awk -F "[[:blank:]:]+" 'NR > 2 { print $6, $8 }' >tmp.txt Speaking of which, this also gives you yet another option for setting localip. Code:
localip=$( ifconfig wlan0 | awk -F "[[:blank:]:]+" '/inet addr/ {print $4}' ) |
All times are GMT -5. The time now is 02:49 PM. |