Find the answer to your Linux question:
Results 1 to 6 of 6
Hello fellow Linuxers! This is the relevant snippet from my traceroute -like-script: Code: ping -c 1 -t $i $domain | egrep -wv 'PING|64 bytes' | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' that extracts ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Dec 2010
    Posts
    15

    Question Novice using GREP


    Hello fellow Linuxers!

    This is the relevant snippet from my traceroute-like-script:
    Code:
    ping -c 1 -t $i $domain | egrep -wv 'PING|64 bytes' | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
    that extracts IPs from ping command output as seen below (IPs are in blue).
    Code:
    PING l.google (209.85.135.147) 56(84) bytes of data.
    From 192.168.1.1 icmp_seq=1 Time to live exceeded
    --- l.google.com ping statistics ---
    1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
    
    PING .l.google (209.85.135.99) 56(84) bytes of data.
    From 95.176.241.10 icmp_seq=1 Time to live exceeded
    --- l.google. ping statistics ---
    1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
    
    PING l.google (209.85.135.106) 56(84) bytes of data.
    # This one has "From so-and-so" line missing and makes GREP exit with a 1. Why? EDIT: Because no matches were found, obviously!
    --- .l.google. ping statistics ---
    1 packets transmitted, 0 received, 100% packet loss, time 0ms
    
    PING l.google (209.85.135.103) 56(84) bytes of data.
    From 72.14.219.148 icmp_seq=1 Time to live exceeded
    --- l.google.com ping statistics ---
    1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
    
    PING l.google (209.85.135.104) 56(84) bytes of data.
    64 bytes from mu-in-f104.1e100 (209.85.135.104): icmp_req=1 ttl=250 time=41.3 ms 
    #finished: from here on GREP exits with 1's 
    How should I check and break the loop (in my script) when the first line "64 bytes from [...]" appears (if using GREP's exit status with echo $? isn't good enough)?

    PS: I had to change URLs to l.google.

    PPS: This is the script's output (above is ping's output):
    Code:
    mytraceroute to google (209.85.135.103)
    192.168.1.1
    0
    95.176.241.10
    0
    1 # this is way I can't rely on GREP's exit code to break the loop
    85.10.0.73
    0
    [...]
    72.14.238.128
    0
    209.85.253.26
    0
    1
    1
    1
    ^C
    Last edited by courteous; 12-05-2010 at 10:46 PM. Reason: added script's output

  2. #2
    Just Joined! barriehie's Avatar
    Join Date
    Apr 2008
    Location
    The Desert!
    Posts
    85
    First thing that comes to mind for this sort of thing would be gawk, the gnu variant of awk. Can do this sort of line matching thing quite well. For instance, (pseudocode):
    Code:
    ping blah blah blah | gawk '{ while ( ( $0 ~ /some_pattern/) || ( $0 ~ /some_other_pattern) ) { print $0 } }'
    This says that while the input line = some pattern or some other pattern then print it. Gawk supports if-else while-do/done etc. Might be an easier tool to use.

    Here's a link about gawk. Gawk: Effective AWK programming - GNU Project - Free Software Foundation (FSF)

    To recap: You want to break the loop when all you're getting for output is a numeric 1?

    Edit: Try this: (it should exit if the line starts with 64 and otherwise print the line. I would ideally do the whole thing using gawk...
    Code:
    ping -c 1 -t $i $domain | egrep -wv 'PING|64 bytes' | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'  | gawk '{ if( $0 ~ /^64 bytes.*$/ ) { exit 1 } else { print $0 } }'
    Last edited by barriehie; 12-05-2010 at 11:18 PM.

  3. #3
    Just Joined!
    Join Date
    May 2006
    Posts
    5
    gawk is easier to master than perl or python, but why are you reinventing traceroute? Before I asked that, I made the slightly embarrassing discovery that my Ubuntu 10.10 system doesn't have traceroute installed on it. It was trivial to correct that using: sudo apt-get install traceroute
    (That command was directly suggested in the error message when I tried to run the not-installed traceroute command. Are you trying to find a way to have traceroute without sudo authority to install the package. None of it seems to be suid, so I expect a copy could be installed under your home directory without needing special privileges (but I haven't tried that),

    Use the Source, Luke!

    Drew

  4. $spacer_open
    $spacer_close
  5. #4
    Just Joined!
    Join Date
    Dec 2010
    Posts
    15

    Nope, still not working.

    barriehie,
    thank you for your effort (I should've replied sooner) ... though it still doesn't work (properly).
    I've removed '64 bytes' from my previous egrep -wv 'PING|64 bytes' (otherwise gawk wouldn't get anything to chew on?) and I also tried to put gawk before IP-extracting grep:
    Code:
    ping -c 1 -t $i $domain | egrep -wv 'PING' | gawk '{ if( $0 ~ /^64 bytes.*$/ ) { exit 1 } else { print $0 } }' | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
    gawk just doesn't do exit 1 What does print $0 do?

    In short, gawk needs only to exit when it finds a line starting as '64 bytes': how do you do that?

    rdrewd,
    why I'm "re-inventing traceroute"? Because my teacher told me to ... and no, I'm not trying to avoid "sudo authority".

  6. #5
    Linux Newbie tetsujin's Avatar
    Join Date
    Oct 2008
    Posts
    117
    Why do you have the -v switch on the call to "egrep"? That causes all lines containing "PING" or "64 bytes" to be eliminated from the output... Aren't those the lines you want to check for IP addresses?

    Maybe this could work:

    Code:
    ping -c 1 -t $TIMEOUT $HOSTNAME | egrep -w 'PING|64 bytes' | (while read a; do if (echo $a | egrep -q '^64 bytes'); then exit 1; else echo $a | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'; fi; done)
    The output of egrep is fed into a loop (run in a subshell) which reads a line at a time (so that we can run grep on each line individually and detect when a line contains "64 bytes") - feeds the line through a "grep" to grep for "64 bytes" and check the result - and then either exit or grep out an IP address.

  7. #6
    Just Joined!
    Join Date
    Dec 2010
    Posts
    15

    Thumbs up Almost there.

    Quote Originally Posted by tetsujin View Post
    Why do you have the -v switch on the call to "egrep"? That causes all lines containing "PING" or "64 bytes" to be eliminated from the output... Aren't those the lines you want to check for IP addresses?
    Only the first "PING" line, the target domain (in #1 post this is google.com).

    Quote Originally Posted by tetsujin View Post
    Maybe this could work:
    Code:
    ping -c 1 -t $TIMEOUT $HOSTNAME | egrep -w 'PING|64 bytes' | (while read a; do if (echo $a | egrep -q '^64 bytes'); then exit 1; else echo $a | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'; fi; done)
    Thank you, I think it works now ... but, why can't I check it with an echo "Target reached."; just before exit 1; (isn't semicolon ; enough)? I did this and this echo got executed more than once!

    Am I doing some BASH-syntax-blunder?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •