linux & solaris - 將網路遮罩 IP 與普通 IP 分開
我有帶有 IP 地址和網路遮罩 IP 的文件
我的目標是從file_with_IPs.txt中剪切網路遮罩 IP ,並將它們粘貼到另一個文件中作為file_with_only_netmask_ips.txt
備註 - 網路遮罩 IP 可以是網路遮罩 IP 的任意組合,例如可以從 xxx.xxx.xxx.xxx/1 到 xxx.xxx.xxx.xxx/32 開始
例如
10.140.4.11 10.140.4.110 255.255.0.0 255.255.255.0 10.219.39.188 10.219.39.200 10.219.39.189 10.219.39.145 10.140.4.12 10.140.4.120 10.219.39.138 10.219.39.140 10.219.39.139 10.219.39.239 255.0.0.0 255.255.0.0 255.255.255.128 255.255.255.192
所以最後我將在file_with_IPs.txt文件中
10.140.4.11 10.140.4.110 10.219.39.188 10.219.39.200 10.219.39.189 10.219.39.145 10.140.4.12 10.140.4.120 10.219.39.138 10.219.39.140 10.219.39.139 10.219.39.239
在file_with_only_netmask_ips.txt我將只有網路遮罩 IP,如下所示:
255.255.0.0 255.255.255.0 255.0.0.0 255.255.0.0 255.255.255.128 255.255.255.192
請建議將網路遮罩 IP 與普通 IP 分開的最佳方法是什麼?
我需要用 ksh shell 編寫程序,我需要在 Linux 和 Solaris 機器上執行這個程序
備註 perl 一種線性 , sed 和 awk 可以在 ksh 腳本中
一種方法
awk
:awk '{ for(i=1;i<=NF;i++) { if($i~/^255/) { netmask[NR]=i>1?netmask[NR]"\t"$i:$i } else { regular[NR]=i>1?regular[NR]"\t"$i:$i } } } END { for(i=1;i<=NR;i++) { if (regular[i]) { print regular[i] > "file_with_IPs.txt" } if (netmask[i]) { print netmask[i] > "file_with_only_netmask_ips.txt" } } }' file
測試:
$ ls file $ cat file 10.140.4.11 10.140.4.110 255.255.0.0 255.255.255.0 10.219.39.188 10.219.39.200 10.219.39.189 10.219.39.145 10.140.4.12 10.140.4.120 10.219.39.138 10.219.39.140 10.219.39.139 10.219.39.239 255.0.0.0 255.255.0.0 255.255.255.128 255.255.255.192 $ awk '{ > for(i=1;i<=NF;i++) { > if($i~/^255/) { > netmask[NR]=i>1?netmask[NR]"\t"$i:$i > } > else { > regular[NR]=i>1?regular[NR]"\t"$i:$i > } > } > } > END { > for(i=1;i<=NR;i++) { > if (regular[i]) { > print regular[i] > "file_with_IPs.txt" > } > if (netmask[i]) { > print netmask[i] > "file_with_only_netmask_ips.txt" > } > } > }' file $ ls file file_with_IPs.txt file_with_only_netmask_ips.txt $ cat file_with_IPs.txt 10.140.4.11 10.140.4.110 10.219.39.188 10.219.39.200 10.219.39.189 10.219.39.145 10.140.4.12 10.140.4.120 10.219.39.138 10.219.39.140 10.219.39.139 10.219.39.239 $ cat file_with_only_netmask_ips.txt 255.255.0.0 255.255.255.0 255.0.0.0 255.255.0.0 255.255.255.128 255.255.255.192
通過“網路遮罩 IP”,您似乎是指所有設置位在左側組合在一起的東西。其中只有 32 個,從 /0 到 /32。您可以在 grep 語句中列出它們(或者,更好的是,在您傳遞給的文件中
grep -f
)。這種方法很乏味,但很容易;
^0\.0\.0\.0$ ^128\.0\.0\.0$ ^192\.0\.0\.0$ ^224\.0\.0\.0$ ⋮
由於它實際上是我們正在尋找的二進制模式,您可以將其轉換回數字,然後對其進行一些位旋轉以確認它與模式匹配。不過,這將是一項實際的程式任務,而不是您與 grep 一起完成的任務。
雖然你可以用 bc 做一些接近的事情。以下是測試方法
$ip
:( echo 'obase=2'; echo "$ip" | sed -e 's/\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/\1*(256^3)+\2*(256^2)+\3*256+\4/' ) bc | grep -q '^1*0*$' && echo yes || echo no
如果你把它分解,echo 告訴 bc 以二進制輸出。然後該
sed
行將 IP 地址轉換為表達式,以計算其數值。255.255.255.0
變成255*(256^3)+255*(256^2)+255*256+0
. 所以bc
看到:obase=2 255*(256^3)+255*(256^2)+255*256+0
它列印出
11111111111111111111111100000000
,然後檢查它以匹配^1*0*$
模式grep
。如果您有一個將 IP 轉換為數字的實用程序,那將消除上述大部分複雜性。不過,可能仍然會比
grep
帶有模式列表的 慢。