2013-03-07 82 views
1

我正在研究子網計算的腳本。到目前爲止,它看起來像這樣(部分):Bash腳本,從obase解析二進制數字符串?

echo "Subnet Address : "$sn1.$sn2.$sn3.$sn4 
echo "BCast Address : "$br1.$br2.$br3.$br4 
echo -e "\nSubnet address in binary" : 
echo "obase=2;$ip1"+"obase=2;$ip2"+"obase=2;$ip3"+"obase=2;$ip4" \ 
    | bc | awk '{printf("%08d",$ip1)}' 
echo -e "\nBroadcast address in binary" : 
echo "obase=2;$br1"+"obase=2;$br2"+"obase=2;$br3"+"obase=2;$br4" \ 
    | bc | awk '{printf("%08d",$br1)}' 

,給了我這樣的輸出:

Subnet address in binary : 
11000010101010100000001100000000 
Broadcast address in binary : 
11000010101010100000001100011111 
  1. 我試圖'{printf("%08d.",$br1)}''{printf(".%08d",$br1)}'到八位位組分開,但我對獲得額外的點開始或結束。
  2. 我想計算netmask有多少個aces,但是我真的無法找到一種方法將echo "obase=2;$br1"+"obase=2;$br2"+"obase=2;$br3"+"obase=2;$br4"| bc | awk的輸出轉換爲字符串,因此我可以對它們進行計數。

有什麼建議?

+1

的例子是不完整的,所以很難說相當這裏發生了什麼上。 – danfuzz 2013-03-07 19:16:56

回答

0

爲了區分八位位組,我會用printfpaste代替,例如:

ip1=127; ip2=0; ip3=0; ip4=1 
printf "%08d\n" $(bc <<<"obase=2; $ip1; $ip2; $ip3; $ip4") | paste -sd. 

或者,如果IP是一個變量:

ip=127.0.0.1 
printf "%08d\n" $(bc <<<"obase=2; ${ip//./;}") | paste -sd. 

輸出:

00001010.00101010.01100110.11111100 

要計算網絡掩碼中1的數量,只需添加它們:

netmask=255.255.255.252 
printf "%08d" $(bc <<<"obase=2; ${netmask//./;}") | grep -o . | paste -sd+ | bc 

輸出:

30 
2

所以你想輸出的格式是:01111111.00000000.00000000.00000001?

嘛,作弊方法,我用的時候我撞我的頭,這是環繞ipcalc:

%ipcalc 127.0.0.1 
Address: 127.0.0.1   01111111.00000000.00000000. 00000001 
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000 
Wildcard: 0.0.0.255   00000000.00000000.00000000. 11111111 
=> 
Network: 127.0.0.0/24   01111111.00000000.00000000. 00000000 
HostMin: 127.0.0.1   01111111.00000000.00000000. 00000001 
HostMax: 127.0.0.254   01111111.00000000.00000000. 11111110 
Broadcast: 127.0.0.255   01111111.00000000.00000000. 11111111 
Hosts/Net: 254     Class A, Loopback 

,然後解我所需要的。運行速度比通過'bc'多次解析速度快。也就是說,如果你不需要的話,沒有必要重新發明輪子。

如果你覺得自己重新發明輪子了一下:

$ echo "obase=2;200" + "obase=2;150" + "obase=2;200" + "obase=2;150" | \ 
    bc | awk '{printf "%08d\." ,$1}' | \ 
    sed -e 's/[.]*$//' 
11001010.10011000.11001010.10010110 

,將讓你你想要的8位二進制輸出格式。

+0

注意,爲了避免在最後得到點,您需要在awk中進行一些跟蹤。 – 2013-03-07 19:24:42

0

兩個快速的解決方案:

$ echo $br1.$br2.$br3.$br4 | 
    perl -F\\\. -anE 'say join ".", map { sprintf "%08b", $_ } @F' 
$ perl -e 'printf("%08b.%08b.%08b.%08b\n", '$br1,$br2,$br3,$br4')'