6

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
TPE
cell 1 below
Free

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.

3
  • 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. Apr 29 '14 at 10:57
  • Will update topic with airport -s output!
    – Bill
    Apr 29 '14 at 19:05
5

You should quote netarray in the for-in loop.

for hit in "${netarray[@]}"
do
     networks[$addloopnr]="$hit"
     let addloopnr++
done
3
  • 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
3
mapfile -t ssids < <(
    airport -s | 
    sed -E '
        1d
        /NONE$/!d
        s/^[[:blank:]]*(.+) [[:xdigit:]:]{17} (...).*/\2 \1/
    ' | 
    sort -k1,1nr | 
    cut -d " " -f2-
)
printf "%s\n" "${ssids[@]}"
HP-Print-93-LaserJet 1102
TPE-Free

adjusting for bash v3

ssids=()
while read -r line; do ssids+=("$line"); done < <(
    airport -s | 
    sed -E '
        1d
        /NONE$/!d
        s/^[[:blank:]]*(.+) [[:xdigit:]:]{17} (...).*/\2 \1/
    ' | 
    sort -k1,1nr | 
    cut -d " " -f2-
)
printf "%s\n" "${ssids[@]}"
7
  • May need bash v4 for mapfile, not sure. 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. Apr 30 '14 at 23:40
  • Try my edit now. 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
0

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")'
1
  • 1
    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.