Shell Script 求教



贊助商連結


頁 : [1] 2

FYI
2011-01-29, 10:45 PM
root@OpenWrt:~# iwlist ath0 scan | grep -B 5 "Encryption key:off"
Cell 01
...
Cell 02 - Address: 00:11:22:33:44:55
ESSID:"WI FLY"
Mode:Master
Frequency:2.412 GHz (Channel 1)
Quality=34/70 Signal level=-62 dBm Noise level=-95 dBm
Encryption key:off
Cell 03
以上是掃描無線基地台的結果再經過grep 篩選後的一部分, 目的是想要找出未加密基地台之中, 訊號最強者的ESSID (可能包含空白), 其他則不重要, 訊號強度為Quality 之後的數字, 以上例為34, 實際可能是1~2 位數, 此外Script 必須能在OpenWrt 之中執行, 而OpenWrt 所支援的指令並不多, 大概基本的grep, awk, sed, sort, find, head, tail 等應該沒問題, 小弟對於shell script 不內行, 尤其關鍵字Quality 和ESSID 分散在不同行, 而Quality 可能是個位數或兩位數:

root@OpenWrt:~# wlanconfig ath0 list scan
SSID BSSID CHAN RATE S:N INT CAPS
aaa 00:aa:bb:bb:dd:ee 1 54M 2:0 100 EPSs
WI FLY 00:11:22:33:44:55 1 54M 34:0 100 EPSs WPA
bbb 01:23:45:67:89:ab 5 54M 12:0 100 EPSs RSN WPA WME
wlanconfig 輸出雖然將SSID 和S:N 放在同一行, 但無法看出是否加密, 此外wlanconfig 和iwlist 掃描結果不一定相同, 所以只能提供參考

小弟不知道該如何排序, 請網友大力協助或給小弟一點提示, 謝謝

贊助商連結


bx2aa
2011-01-30, 02:47 AM
把 五行合併
sed -e :a -e "$!N;s/\n\(.*\)/\1 /;ta" -e "P;D"

bx2aa
2011-01-30, 02:54 PM
type 1.txt |grep -B 5 "Encryption key\:off" | sed -e :a -e "$!N;s/\n\(.*\)/\1 /;ta" - "P;D" | gawk "NF == 21 {print $6,$7,$13;}; NF == 20 {print $6,$12;}"

ESSID:"WIFLY" Quality=34/70

type 1.txt |grep -B 5 "Encryption key\:off" | sed -e :a -e "$!N;s/\n\(.*\)/\1 /;ta" - "P;D" | gawk "NF == 21 {print $6,$7,$13;}; NF == 20 {print $6,$12;}"

ESSID:"WI FLY" Quality=34/70

FYI
2011-01-31, 05:29 AM
感謝bx2aa 兄的熱心協助, 先前的範例只是為了方便說明, 其實還可以更精簡, 為了便於測試, 小弟把過濾條件 "Encryption key:off" 暫時改成 "Encryption key:on", 輸出範例如下:

root@OpenWrt:~# iwlist ath0 scan | grep -B 4 'Encryption key:on' | grep -E 'ESSID:|Quality='
ESSID:"aaa"
Quality=2/70 Signal level=-93 dBm Noise level=-95 dBm
ESSID:"FON_AP"
Quality=34/70 Signal level=-62 dBm Noise level=-95 dBm
ESSID:"bbb"
Quality=12/70 Signal level=-83 dBm Noise level=-95 dBm
接著再以sed & sort 排列出所要的結果:

root@OpenWrt:~# iwlist ath0 scan | grep -B 4 'Encryption key:on' | grep -E 'ESSID:|Quality=' | sed -e '$!N;s/\n//' -e '/Quality=[0-9]\//s/=/=0/' -e 's/^.*\"\(.*\)\".*y=\(.*\)\/.*$/\2 \1/' | sort -r
34 FON_AP
12 bbb
02 aaa
最後以head & sed 找出訊號最強的AP

root@OpenWrt:~# iwlist ath0 scan | grep -B 4 'Encryption key:on' | grep -E 'ESSID:|Quality=' | sed -e '$!N;s/\n//' -e '/Quality=[0-9]\//s/=/=0/' -e 's/^.*\"\(.*\)\".*y=\(.*\)\/.*$/\2 \1/' | sort -r | head -n 1 | sed 's/^...//'
FON_AP
bx2aa 兄若有興趣的話不妨也玩一玩, 小弟最終目的是要弄一個Universal Wireless Repeater, 目前還在前置作業的階段

謝謝收看

FYI
2011-01-31, 05:32 AM
參考資料:

THE SED FAQ (http://sed.sourceforge.net/grabbag/tutorials/sedfaq.txt)
SED -- A Non-interactive Text Editor (http://sed.sourceforge.net/grabbag/tutorials/sed_mcmahon.txt)

FYI
2011-01-31, 02:28 PM
由於平常除了回答OpenWrt/DD-WRT 問題之外, 小弟幾乎不會用到Linux, 所以小弟其實並不熟悉Linux, 所懂的也僅止於可能會用到的部份, 對於sed & awk 就更不熟悉了, 這次惡補sed 語法讓小弟產生一些疑問:
請問sed 是循序處理外部指令的嗎? 也就是說一個-e 指令處理完整個檔案之後再處理第二個-e 指令? 還是從資料讀取一行, 然後循序處理每一個-e 指令, 再讀取下一行資料? 或者外部指令有優先權之分, 例如是否 'N', 'H' 等會優先執行?
-e '$!N;s/\n//' 在sed 之中的前後位置有何影響?
原本小弟打算先處理到:

aaa
02
FON_AP
34
bbb
12
然後以-e '$!N;s/\n//' 把兩行併成一行, 但結果卻成為:

aaa Quality=2/70 Signal level=-93 dBm Noise level=-95 dBm
FON_AP Quality=34/70 Signal level=-62 dBm Noise level=-95 dBm
bbb Quality=12/70 Signal level=-83 dBm Noise level=-95 dBm
雖然小弟知道單獨執行 sed '$!N;s/\n//' 結果會是正確的, 但是小弟不瞭解為何把它插入到上一個sed 指令的最後, 結果卻大不相同

bx2aa
2011-01-31, 07:28 PM
type 2.txt
ESSID:"aaa"
Quality=2/70 Signal level=-93 dBm Noise level=-95 dBm
ESSID:"FON_AP"
Quality=34/70 Signal level=-62 dBm Noise level=-95 dBm
ESSID:"bbb"
Quality=12/70 Signal level=-83 dBm Noise level=-95 dBm

type 2.txt | sed -e "$!N;s/\n\(.*\)/\1/g" | gawk "{print $1,$2}" | sed -e "s/ESSID\:\"\(.*\)\" Quality=\(.*\)\/70/\2 \1/g" | sort | tail -n 1
34 FON_AP

type 2.txt | sed -e "$!N;s/\n\(.*\)/\1/g" | gawk "{print $2,$1}" | sed -e "s/Quality=\(.*\)\/70 ESSID\:\"\(.*\)\"/\2 \1/g;" | sort -r -k 2 | head -n 1
FON_AP 34

FYI
2011-02-01, 06:06 AM
忘了說明小弟找不到Fon 可用的gawk, 不過改用awk 倒也沒問題

"sort -r -k 2" 又學到一招! 謝了! 只不過無法排除飯店的SSID 包含空白的可能性, 為了安全起見, 小弟還是選擇把Quality 放前面再排序

此外, 乍看bx2aa 兄的語法並未特別處理 "Quality=" 之後的數字, 可能小弟所舉的範例並不恰當, 應該把aaa 的Quality 由2/70 改為5/70:

ESSID:"aaa"
Quality=5/70 Signal level=-93 dBm Noise level=-95 dBm
ESSID:"FON_AP"
Quality=34/70 Signal level=-62 dBm Noise level=-95 dBm
ESSID:"bbb"
Quality=12/70 Signal level=-83 dBm Noise level=-95 dBm
那就可以發現一位數和兩位數的排序問題, 不過沒關係, 反正問題已經解決, 再一次感謝bx2aa 兄, 反倒是完全不見tvirus 兄的蹤影, 人情冷暖由此可見...

補充:
歹謝歹謝! 小弟駑鈍, 原來只要用 "sort -n" 就可以解決數字排序問題, 慚愧慚愧!

tvirus
2011-02-01, 01:22 PM
那就可以發現一位數和兩位數的排序問題, 不過沒關係, 反正問題已經解決, 再一次感謝bx2aa 兄, 反倒是完全不見tvirus 兄的蹤影, 人情冷暖由此可見...

人家Shell script很弱的 Orz
我是因為比較會寫php
甚至連Cacti的部份script取值都是用執行php取值的方式進行...
我不是像朋友公司的某人一樣,一大堆我想不到的事,都可以用Shell script解決 :Q

所以...

你看你看!!Alan大也沒出現啊 (拉

FYI
2011-02-02, 01:37 AM
就是因為上回看到tvirus 兄的Cacti script 運用awk 的語法出神入化, 所以才會對tvirus 兄非常崇拜, 沒想到現在竟然形像破滅, 至於Alan 兄, 別叫小弟換AP 那就感激不盡了

ESSID:"aaa"
Quality=5/70 Signal level=-90 dBm Noise level=-95 dBm
ESSID:"Hotel California"
Quality=34/70 Signal level=-62 dBm Noise level=-95 dBm
ESSID:"bbb"
Quality=12/70 Signal level=-83 dBm Noise level=-95 dBm

root@OpenWrt:~# iwlist ath0 scan | grep -B 4 'Encryption key:on' | grep -E 'ESSID:|Quality=' | sed -e '$!N;s/\n//' -e 's/^.*\"\(.*\)\".*=\(.*\)\/.*$/\2 \1/' | sort -r -n
34 Hotel California
12 bbb
5 aaa
root@OpenWrt:~# iwlist ath0 scan | grep -B 4 'Encryption key:on' | grep -E 'ESSID:|Quality=' | sed -e '$!N;s/\n//' -e 's/^.*\"\(.*\)\".*=\(.*\)\/.*$/\2 \1/' | sort -r -n | head -n 1 | sed 's/^[0-9]* //'
Hotel California