Here is a simple Bash function that uses only Bash internals and spawns only one sub-shell:
#!/bin/bash function iwScan() { # disable globbing to avoid surprises set -o noglob # make temporary variables local to our function local AP S # read stdin of the function into AP variable while read -r AP; do ## print lines only containing needed fields [[ "${AP//'SSID: '*}" == '' ]] && printf '%b' "${AP/'SSID: '}\n" [[ "${AP//'signal: '*}" == '' ]] && ( S=( ${AP/'signal: '} ); printf '%b' "${S[0]},";) done set +o noglob } iwScan <<< "$(iw wlan0 scan)"
Output:
-66.00,FRITZ!Box 7312 -56.00,ALICE-WLAN01 -78.00,o2-WLAN93 -78.00,EasyBox-7A2302 -62.00,dlink -74.00,EasyBox-59DF56 -76.00,BELAYS_Network -82.00,o2-WLAN20 -82.00,BPPvM
The function can be easily modified to provide additional fields by adding the necessary filter while reading -r AP while-loop, for example:
[[ "${AP//'last seen: '*}" == '' ]] && ( S=( ${AP/'last seen: '} ); printf '%b' "${S[0]},";)
Output:
-64.00,1000,FRITZ!Box 7312 -54.00,492,ALICE-WLAN01 -76.00,2588,o2-WLAN93 -78.00,652,LN8-Gast -72.00,2916,WHITE-BOX -66.00,288,ALICE-WLAN -78.00,800,EasyBox-59DF56 -80.00,720,EasyBox-7A2302 -84.00,596,ALICE-WLAN08