Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I run the following command:

sudo iwlist eth0 scan

and get output that looks like this:

Cell 01 - Address: AB:CD:EF:12:34:56
          ESSID:"name"
          Protocol:IEEE 802.11g
          Mode:master
          Frequency:2.417 GHz (Channel 2)
          Encryption key:on

I won't bother filling it all out, as I'm trying to fix a laptop and I cannot simply copy the output.

How can I use built-in tools such as grep, awk, sed, etc. to fetch information given certain criteria? For example:

I want to grab the mac address when knowing the essid. I also don't want to rely on the Cell # or line positions. Knowing common information, like the word Address before the mac is fine.

Expected output:

AB:CD:EF:12:34:56

I want to use it in a variable, like so:

sudo iwconfig eth1 ap $(command)

Where command would result in the expected result. If there's another way of pushing the result as a variable using > or something, that works as well. (command > sudo iwconfig eth1 ap $1)

Thanks.

share|improve this question
    
Those are the tools to look into (sed, awk, and grep). Please update your question to include what you want the output to look like. Hard to know how to answer without a sample output. –  bodhi.zazen Jan 26 '12 at 2:02
    
@bodhi.zazen I edited my question to include expected output. –  Brian Graham Jan 26 '12 at 2:06
    
Is there any search involved ? You can get the mac of your mac with ip addr show eth0 | awk '/link\// {print $2}' Change eth0 to the desired device. You can sudo iwconfig eth1 ap $(ip addr show eth0 | awk '/link\// {print $2}') adjust your interfaces as needed. –  bodhi.zazen Jan 26 '12 at 2:16
1  
The asker is looking for the MAC address of wireless access points, not of the computer's network device. There has to be some degree of searching involved since there may be many nearby access points with different MAC addresses at any given moment. –  pablomme Jan 26 '12 at 2:22
add comment

3 Answers 3

up vote 1 down vote accepted

AWK is very powerful and perfect for this. Basically, you want to:

  1. Save the address in the address line
  2. If the ESSID matches your value, print it

The shortest version I could think of:

sudo iwlist wlan0 scan|awk '/Address:/{a=$5}/ESSID:"name"/{print a}'

/pattern/ is a regular expression that is compared with input. If it matches, the part after the curly brackets ({...}) is executed.

The awk command processes input line by line:

  1. If a line matches Address:, the fifth field is stored in a variable named a. Fields are whitepace-delimited lines.
  2. If a line matches ESSID:"name", variable a is printed (the last address that matched).

Both rules are executed, but 1 comes before 2 so a is always set.

Manual page for awk

share|improve this answer
    
Can you explain how this works? –  Brian Graham Feb 1 '12 at 3:07
    
@BrianGraham I thought it was pretty self-explanatory. Added some extra details. –  Lekensteyn Feb 1 '12 at 13:34
add comment

My personal preference for these things is pure bash. The script below should do what you are looking for.

get_mac_of_essid() {
 target_essid="$1"
 [ -z "$target_essid" ] && return
 interface=eth0

 # Ask for password now instead of in the middle of pipe below
 sudo -v

 mac="" ; essid=""
 {
  while read line ; do
   set -- $line
   if [ "$1" = Cell ] ; then
    # New network, so reset variables
    mac="" ; essid=""
    shift 3
   fi
   case "$1" in
   Address:)
    mac="$2" # MAC is on this line, second field
    ;;
   ESSID:*)
    essid="${1#ESSID:}" # ESSID is on this line, first field after ':'
    essid="${essid#\"}" # Remove duoble quote at start
    essid="${essid%\"}" # Remove double quote at end
    ;;
   esac
   if [ "$essid" = "$target_essid" ] && [ ! -z "$mac" ] ; then
    echo "$mac" ; return
   fi
  done
 } < <(sudo iwlist $interface scan)
}

After pasting the above into your terminal, you should be able to run get_mac_of_essid name to get the MAC address associated with network "name" as many times as needed.

share|improve this answer
    
Nice script, hope it is what the OP is after =) –  bodhi.zazen Jan 26 '12 at 2:26
    
This would work, if I had access to the filesystem. I cannot write information to disk, it's been corrupted. –  Brian Graham Jan 26 '12 at 3:00
    
There is no writing involved - the pipe is via a file descriptor for which no physical file should be created. You've tried it and it doesn't work? EDIT: ah, I see what you mean, the writing of the script itself. One sec, I'll update my post. –  pablomme Jan 26 '12 at 3:09
    
There, that should do it. –  pablomme Jan 26 '12 at 3:18
add comment

I suggest learning the cut command. It makes this task easy. Forgive the echo, but I wanted to demonstrate on the original data.

$ echo 'Cell 01 - Address: AB:CD:EF:12:34:56  
          ESSID:"name"  
          Protocol:IEEE 802.11g  
          Mode:master  
          Frequency:2.417 GHz (Channel 2)  
          Encryption key:on' | egrep Address | cut '-d:' -f2-  
 AB:CD:EF:12:34:56  

$ echo 'Cell 01 - Address: AB:CD:EF:12:34:56  
          ESSID:"name"  
          Protocol:IEEE 802.11g  
          Mode:master  
          Frequency:2.417 GHz (Channel 2)  
          Encryption key:on' | egrep ESSID: | cut '-d"' -f2
name
share|improve this answer
    
How would this work if there is more than one cell (there are 15 on my laptop)? What would I do to find Address, given ESSID? –  Brian Graham Jan 26 '12 at 14:59
1  
I think you mean something like this (assuming the ESSID value you want the address for is "fnorg722"): sudo iwlist wlan0 scanning | egrep 'ESSID|Address' | cut -d: -f2- | grep -B 1 fnorg722 ` 14:D6:4D:2D:5F:AE` "fnorg722" –  waltinator Jan 30 '12 at 19:44
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.