I have a problem I can't seem to figure out.. I'm making a script I will run in OSX to help me stay connected to open wifi hotspots. I am reading all surrounding wifi networks into a muntiline variable. These wifi networks have sometimes spaces in their names, which presents a problem for me. I want to loop through this multiline variable that contains spaces and add each line as it is to a new array cell. Adding my code below. Anyone that can help me sort this out?

#Looks for available networks
netarray=(`airport -s |
awk '$NF=="NONE"{print}' | 
cut -c 1-32,51-54 | 
sort -r -n -k 1.34,1.36 | 
awk '{$NF=""; print}' | 
sed -e 's/ $//' `)

#Test text added here
echo "netarray below"
echo "$netarray"
echo "cell 0 below"
echo ${netarray[0]}
echo "cell 1 below"
echo ${netarray[1]}
echo ""
#Until here

This gives me this output (See that TPE Free is cut):

netarray below
TPE Free HP-Print-93-LaserJet 1102
cell 0 below
cell 1 below

airport -s gives me this output currently:

                        SSID BSSID             RSSI CHANNEL HT CC SECURITY (auth/unicast/group)
                   fuck this 00:1f:1f:27:e4:ac -79  11      N  -- WEP
                       BigA2 34:08:04:c3:9a:14 -85  11      N  US WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP) 
                    TPE Free 78:cd:8e:a6:ff:30 -90  10      N  T9 NONE
                     CHT3826 b0:b2:dc:c3:91:77 -82  11      Y  -- WPA2(PSK/AES/AES) 
                          KK 00:e0:4c:ac:e1:05 -84  11      N  -- WEP
                 perfectidea f8:1a:67:53:eb:da -79  9,-1    Y  -- WPA2(PSK/AES/AES) 
                   tfb_18_28 b0:c7:45:ac:18:98 -87  7,+1    Y  -- WPA2(PSK/AES,TKIP/TKIP) 
   HP-Print-93-LaserJet 1102 08:3e:8e:7c:04:93 -86  6       N  -- NONE
                   SG-OFFICE 74:d0:2b:dc:67:64 -80  6       Y  -- WPA2(PSK/AES/AES) 
                      holo15 b8:55:10:bd:3e:70 -82  5,-1    Y  -- WPA(PSK/AES/AES) WPA2(PSK/AES/AES) 
             TOTOLINK N300RA 78:44:76:dd:bb:b4 -82  5,+1    Y  -- WPA(PSK/AES/AES) WPA2(PSK/AES/AES) 
               ezstay 15F-28 78:44:76:dc:f1:a0 -85  2,+1    Y  KR WPA(PSK/AES/AES) WPA2(PSK/AES/AES) 
                      12F-32 20:10:7a:9f:d9:c1 -59  1       Y  -- WPA(PSK/AES,TKIP/TKIP) 

The awk on airport command just cuts out the names of the Open networks and puts them on separate rows.

  • Any more suggestions? Please? – Bill Apr 28 '14 at 9:57
  • You might want to post some example output of airport -s for people who don't run OSX. – Adrian Frühwirth Apr 29 '14 at 10:57
  • Will update topic with airport -s output! – Bill Apr 29 '14 at 19:05
mapfile -t ssids < <(
    airport -s | 
    sed -E '
        s/^[[:blank:]]*(.+) [[:xdigit:]:]{17} (...).*/\2 \1/
    ' | 
    sort -k1,1nr | 
    cut -d " " -f2-
printf "%s\n" "${ssids[@]}"
HP-Print-93-LaserJet 1102

adjusting for bash v3

while read -r line; do ssids+=("$line"); done < <(
    airport -s | 
    sed -E '
        s/^[[:blank:]]*(.+) [[:xdigit:]:]{17} (...).*/\2 \1/
    ' | 
    sort -k1,1nr | 
    cut -d " " -f2-
printf "%s\n" "${ssids[@]}"
  • May need bash v4 for mapfile, not sure. – glenn jackman Apr 29 '14 at 21:09
  • Unfortunately getting this error in OSX: /Applications/connect.sh: line 19: mapfile: command not found – Bill Apr 30 '14 at 21:25
  • The bash on OSX is too old. – glenn jackman Apr 30 '14 at 23:40
  • Try my edit now. – glenn jackman Apr 30 '14 at 23:42
  • Great, thank you. Have a problem when trying to list the networks still that the network names are cut.. doing this for loop but still cutting on spaces, any suggestions?: network_selection=1 echo "These are the available open networks, sorted by signal strength:" for line in ${ssids[@]} do echo $network_selection ") " "$line" let network_selection++ done – Bill May 1 '14 at 4:15

You should quote netarray in the for-in loop.

for hit in "${netarray[@]}"
     let addloopnr++
  • I've tried that, but then what happens is that all networks found is added to networks[0].. – Bill Apr 27 '14 at 2:38
  • I need all networks found to be added to own array cells, and they are currently on own rows in $netarray – Bill Apr 27 '14 at 2:39
  • I'm thinking I need to use IFS but not really sure how to.. – Bill Apr 27 '14 at 3:05

just store the command result directly to an array

this does require fiddling with IFS to get it to split only on newlines

note that $'\n' for newline may be something of a bash-ism; ymmv w/zsh

OIFS=$IFS IFS=$'\n' netarray=(`airport -s |
awk '$NF=="NONE"{print}' | 
cut -c 1-32,51-54 | 
sort -r -n -k 1.34,1.36 | 
awk '{$NF=""; print}' | 
sed -e 's/ $//' `) IFS=$OIFS

e.g. based on your sample output,

$ typeset -p netarray
declare -a netarray='([0]="HP-Print-93-LaserJet 1102" [1]="TPE-Free")'
  • This is perfect for adding them directly to array, but problem is still that if a network name is "Network Name", Network will be in netarray[0] and Name will be in netarray[1]. That's the actual problem for me for which I think I need to use IFS somehow.. – Bill Apr 30 '14 at 5:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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