Determine an SSIDs Index Value in the Preferred Networks List

Solution 1:

Formulating the problem in terms of “which index does my corporate network have?” makes the problem more complicated. Since you only want to know whether it's at the top of the list, just check whether the top of the list is your corporate network.

Zsh

Here's a way to put the network names into an array in zsh. This uses three nested parameter expansion constructs around a command substitution:

  • ${(f)$(…)} splits the output of the command substitution into lines (f flag).
  • ${(@)…##[[:space:]]##} strips off the prefix matching the pattern [[:space:]]##, meaning one or more whitespace characters. ([[:space:]]#, meaning zero or more whitespace characters, would be equivalent, since removing an empty string has no effect.) The goal is to strip the leading tab. ${(@)…#$'\t'} would work too, but would be fragile in case a different version of macOS uses a different amount of spacing. The pattern needs setopt extended_glob, which is off by default. The @ flag ensures that the data is processed as a list of strings (list of lines from the previous step) and not as a single string.
  • "${(@)…[2,-1]}" selects the elements of the array from the second one (zsh arrays start at 1) to the last one (-1). This removes the “Preferred networks on …” line. The @ flag ensures that each line ends up in a separate array element. The double quotes ensure that spaces inside a network name do not cause each word of a name to end up in a separate array element.
setopt extended_glob
networks=("${(@)${(@)${(f)$(networksetup -listpreferredwirelessnetworks en0)}##[[:space:]]##}[2,-1]}")

Now you can check whether the first element is what you want:

if [[ $networks[1] != "HOME-OFFICE" ]]; then
  …
fi

If you do want the (1-based) index of a network name, you can use the i array subscript flag.

echo $networks[(i)"HOME-OFFICE"]

Sed

You can use sed to extract a specific line by number. Line numbers start at 1. Use the -n command line flag to suppress printing and the p command to print the desired line, or use the d command to delete all lines except the desired one. Use the s command to strip off leading whitespace; note that there is a literal tab character and a space inside the brackets. You can add the suffix p to the s command to print its output without a separate p command.

preferred_network=$(networksetup -listpreferredwirelessnetworks en0 | sed -n '2s/^[  ]*//p')

or

preferred_network=$(networksetup -listpreferredwirelessnetworks en0 | sed -n '2!d; s/^[  ]*//')

You can get the 2-based index of an element by name with sed by applying the = command to the line(s) matched by a regular expression.

line_number=$(networksetup -listpreferredwirelessnetworks en0 | sed -n 's/^[     ]*//; /^HOME-OFFICE$/=')
zero_based_index=$((line_number - 2))

Awk

You can use awk to extract a specific line by number. Line numbers start at 1, and the number of the current line is in the NR variable. After matching the desired line, remove the leading whitespace with the sub command, then print the line. Awk recognizes \t to mean a tab character.

preferred_network=$(networksetup -listpreferredwirelessnetworks en0 | awk 'NR==2 {sub(/^[\t ]*/, ""); print}')

If you want the number of a line with a specific content, you can match the line with a regular expression or by doing a string comparison ($0 contains the whole line without a terminating newline character), then print NR.

home_office_zero_based_index=$(networksetup -listpreferredwirelessnetworks en0 | awk '{sub(/^[\t ]*/, "")} $0 == "HOME-OFFICE" {print NR - 2})'

or

home_office_zero_based_index=$(networksetup -listpreferredwirelessnetworks en0 | awk '/^[\t ]HOME-OFFICE$/ {print NR - 2})'