原來,解決問題只要短短的一行指令,相信這是許多程式設計人員嚮往的事
最近工作上需要從dhcpcd 取得一些額外的資訊,所以在system call 所沒有有提供的部份,就要從記錄檔裡分析
通常,我們在 linux 下常見的文字檔是DSV 格式(Delimiter-Separated Values)像是/etc/passwd 或是以Space 分隔
在Windows 則常見 INI 格式
以往要取得這類文件的某行或某列的特定資料,通常會寫個程式,然後開檔,一行一行讀取,讀到某行,再進行分析,這樣的做法真的很累,以前我就是這樣做的
而現在,grep 與 sed ,或是 awk 幫我完成大部份工作
例1:
資料檔 aa.txt
Destination Gateway Genmask Flags Metric Ref
192.168.100.0 * 255.255.255.0 U 3 1
172.16.100.0 * 255.255.255.0 U 5 0
172.16.200.0 * 255.255.255.0 U 3 0
default 172.16.100.73 255.255.255.0 U 3 0
FILE *fp;
fp = popen("cat aa.txt | grep default |awk '{print $2}'","r");
if (fp !=NULL)
{
fgets(buf,16,fp);
pclose(fp);
}
使用grep 與 awk 分析資料再使用popen()開啟管線,取回的buf,就是172.16.100.73例2:
資料檔 dhcpcd.info
[dhcpcd]
IPADDR=172.16.100.239
NETMASK=255.255.255.0
NETWORK=172.16.100.0
BROADCAST=172.16.100.255
GATEWAY=172.16.100.73
DNS=192.168.1.254
DHCPSIADDR=172.16.100.73
DHCPCHADDR=00:05:65:71:1F:EA
DHCPSHADDR=00:90:CC:40:25:F9
FILE *fp;
fp = popen("cat dhcpcd.info |awk -F = '/GATEWAY/{print $2}'","r");
if (fp !=NULL)
{
fgets(buf,16,fp);
pclose(fp);
}
使用awk 取得 Name=Value 格式的資料,這種格式常見於 windows INI 最後的結果buf 就是我們要的 172.16.100.73 (Gateway Address)
解說: awk -F fs 意指,設定分隔的字串,在這個例子裡,資料是以 = 符號區分欄位的
所以 fs 要設為 = 符號,/GATEWAY 意指,搜尋GATEWAY 的那一行,
/{print $2} 意指,列印出第二欄的資料
awk 真的是很值得學習的script ,不只在 linux 才有,windows 平台也有喔(按此下載)
參考資料:
Scripts 大集合
AWK Tutorial Guide
沒有留言:
張貼留言