Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
    
Any more suggestions? Please? –  Bill Apr 28 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 at 10:57
    
Will update topic with airport -s output! –  Bill Apr 29 at 19:05

4 Answers 4

up vote 1 down vote accepted
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[@]}"
share|improve this answer
    
May need bash v4 for mapfile, not sure. –  glenn jackman Apr 29 at 21:09
    
Unfortunately getting this error in OSX: /Applications/connect.sh: line 19: mapfile: command not found –  Bill Apr 30 at 21:25
    
The bash on OSX is too old. –  glenn jackman Apr 30 at 23:40
    
Try my edit now. –  glenn jackman Apr 30 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 at 4:15

You should quote netarray in the for-in loop.

for hit in "${netarray[@]}"
do
     networks[$addloopnr]="$hit"
     let addloopnr++
done
share|improve this answer
    
I've tried that, but then what happens is that all networks found is added to networks[0].. –  Bill Apr 27 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 at 2:39
    
I'm thinking I need to use IFS but not really sure how to.. –  Bill Apr 27 at 3:05
_dec_data() { . /dev/fd/5 ; } 5<<-DATA_FN
        _${1}_data() { cmd="\$*" ; . /dev/fd/4 ; eval "\$cmd"
        } 4<<-\DATA
                set -- $( sed "s/'/'\''/g;s/.*/'&' \\\/" ) $( shift ; printf "'%s' " "$@" )
        DATA
DATA_FN

cat <<\AIRPORT |
                        SSID BSSID             RSSI CHANNEL HT CC SECURITY (auth/unicast/group)
                        fuck 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)
AIRPORT
{
_dec_data air
        _air_data 'printf "Arg count\t:\t%d\n" "$#"'
        _air_data 'eval echo "\$$#"'
        _air_data 'printf %s\\n "$9" "$10" "$11"' | {
        _dec_data air2 "and some more stuff!"
                _air2_data 'printf %s\\n "$@"'
} ; }

#OUTPUT#
Arg count       :       14
SSID BSSID RSSI CHANNEL HT CC SECURITY (auth/unicast/group)4
   HP-Print-93-LaserJet 1102 08:3e:8e:7c:04:93 -86  6       N  -- NONE
                        SSID BSSID             RSSI CHANNEL HT CC SECURITY (auth/unicast/group)0
                        SSID BSSID             RSSI CHANNEL HT CC SECURITY (auth/unicast/group)1
 and some more stuff!
share|improve this answer

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")'
share|improve this answer
    
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 at 5:06
    
d'oh. fixed now. thanks! –  Aaron Davies May 1 at 20:49

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.