7

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, 2014 at 9:57
  • You might want to post some example output of airport -s for people who don't run OSX. Apr 29, 2014 at 10:57
  • Will update topic with airport -s output!
    – Bill
    Apr 29, 2014 at 19:05

4 Answers 4

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, 2014 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, 2014 at 2:39
  • I'm thinking I need to use IFS but not really sure how to..
    – Bill
    Apr 27, 2014 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, 2014 at 21:09
  • Unfortunately getting this error in OSX: /Applications/connect.sh: line 19: mapfile: command not found
    – Bill
    Apr 30, 2014 at 21:25
  • The bash on OSX is too old. Apr 30, 2014 at 23:40
  • Try my edit now. Apr 30, 2014 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, 2014 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, 2014 at 5:06
0

I've used this on Linux. Omit the quotes on the array variable. You can set IFS to the newline as follows:

IFS=$'\n'
netarray=`airport -s`
for hit in ${netarray[@]} ; do
    networks[$addloopnr]="$hit"
    let addloopnr++
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .