解析iw wlan0扫描输出

Ari*_*nen 10 bash awk parsing sed

我编写了wlan manager脚本来处理open/ad-hoc/wep/wpa2网络.现在我试图解析iw wlan0扫描输出,以便为我的脚本获得良好的扫描功能.我的目标是得到这样的输出:

SSID        channel     signal      encryption
wlan-ap     6           70%         wpa2-psk
test        1           55%         wep
Run Code Online (Sandbox Code Playgroud)

我已经获得的是这样的输出:

$ iw wlan0 scan | grep 'SSID\|freq\|signal\|capability' | tac
SSID: Koti783
signal: -82.00 dBm
capability: ESS Privacy ShortPreamble SpectrumMgmt ShortSlotTime (0x0531)
freq: 2437
Run Code Online (Sandbox Code Playgroud)

我一直在尝试研究bash/sed/awk,但还没有找到一种方法来实现我的尝试.那么实现这一目标的好方法是什么?

Ari*_*nen 11

这是我基于Sudo_O答案的最终解决方案:

$1 == "BSS" {
    MAC = $2
    wifi[MAC]["enc"] = "Open"
}
$1 == "SSID:" {
    wifi[MAC]["SSID"] = $2
}
$1 == "freq:" {
    wifi[MAC]["freq"] = $NF
}
$1 == "signal:" {
    wifi[MAC]["sig"] = $2 " " $3
}
$1 == "WPA:" {
    wifi[MAC]["enc"] = "WPA"
}
$1 == "WEP:" {
    wifi[MAC]["enc"] = "WEP"
}
END {
    printf "%s\t\t%s\t%s\t\t%s\n","SSID","Frequency","Signal","Encryption"

    for (w in wifi) {
        printf "%s\t\t%s\t\t%s\t%s\n",wifi[w]["SSID"],wifi[w]["freq"],wifi[w]["sig"],wifi[w]["enc"]
    }
}'
Run Code Online (Sandbox Code Playgroud)

输出:

$ sudo iw wlan0 scan | awk -f scan.awk
SSID        Frequency   Signal      Encryption
netti       2437        -31.00 dBm  Open
Koti783     2437        -84.00 dBm  WPA
WLAN-AP     2462        -85.00 dBm  WPA
Run Code Online (Sandbox Code Playgroud)


uml*_*ute 5

尝试解析用于人类阅读的程序的复杂输出(而不是解析机器)通常是不好的做法.

例如,输出iw可能会根据系统的语言设置和/或版本而改变iw,只留下一个仅适用于您的开发机器的"管理器".

相反,您可能会使用相同的接口iw来获取它的信息:库后端libnl

你可能也想看看在wireless-tools(iwconfig,iwlist,...)使用该libiw库.


Chr*_*our 5

这是一个GNU awk可以帮助您获取每个唯一BSS的SSID和通道的脚本:

/^BSS / {
    MAC = $2
}
/SSID/ {
    wifi[MAC]["SSID"] = $2
}
/primary channel/ {
    wifi[MAC]["channel"] = $NF
}

# Insert new block here

END {
    printf "%s\t\t%s\n","SSID","channel"

    for (w in wifi) {
        printf "%s\t\t%s\n",wifi[w]["SSID"],wifi[w]["channel"]
    }
}
Run Code Online (Sandbox Code Playgroud)

考虑到你一直在做的所有研究,你应该很容易添加新的信号和加密块.

将脚本保存到文件中,如下wifi.awk所示:

$ sudo iw wlan0 scan | awk -f wifi.awk
Run Code Online (Sandbox Code Playgroud)

输出将采用格式化的请求:

SSID        channel
wlan-ap     6
test        1
Run Code Online (Sandbox Code Playgroud)

  • 如果你幸运地使用gawk而不是传统的Awk,那就太棒了.OpenWrt中的awk命令来自Busybox,不支持多维数组. (2认同)

小智 5

这是一个简单的 Bash 函数,它只使用 Bash 内部结构并且只产生一个子 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)"
Run Code Online (Sandbox Code Playgroud)

输出:

-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
Run Code Online (Sandbox Code Playgroud)

通过在 while read -r AP while-loop 中添加必要的过滤器,可以轻松修改该函数以提供其他字段,例如:

[[ "${AP//'last seen: '*}" == '' ]] && ( S=( ${AP/'last seen: '} ); printf '%b' "${S[0]},";)
Run Code Online (Sandbox Code Playgroud)

输出:

-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
Run Code Online (Sandbox Code Playgroud)