2005年12月23日 星期五

好用的 awk 命令

使用 awk 命令做 Linux 上的帳號批次管理,我已經用很久了。真的很好用!

剛好今天應教學組長的要求,重設了一個班學生的密碼,順便記下來吧!

以下是我下的指令:

awk -F: '/:207-/
{
cmd="echo newpassword" | passwd --stdin "$1;
print cmd;
system(cmd)
}'
/etc/passwd

這個指令的意思是,從 /etc/passwd 系統帳號檔案裡面抓出 207 班的學生帳號資料,並且把新密碼逐一設定給取出的帳號。

整個命令的重點在利用 awk 做批次處理。 awk 也算是一種程序語言,上面的寫法是我最常用的型式:

awk -F: '/正規表示法/
{
cmd="命令字串";
print cmd;
system(cmd)
}'
/etc/passwd

第一行的 -F: ,是用來設定欄位分格字元的,也就是用 passwd 檔案裡的冒號(:)分隔一列的資料成多個欄位,每個欄位可以在大括號裡用 $1、$2、$3… 當成變數使用。如果不是 passwd 檔,而是其他格式的文字檔呢?比如 Excel 的 csv 格式檔案呢?!這也是我常用的格式,這時,要使用 awk 的內定正規表示法 /BEGIN/ ,在原來的正規表示法之前再加一段:

/BEGIN/ {FS=","; RS=" "}

也就是在開始執行其他命令之前,先執行 FS=',' (用逗號做欄位分隔字元) 以及 RS=' ' (用 DOS 的文字換行字元 CR LF 做資料分隔字元,在 *nix 裡的文字檔只用 做文字換行字元)

第二行的 cmd="命令字串" 則是要執行的帳號管理命令。例如上面的

cmd="echo newpasswd | passwd --stdin "$1;

這裡的 $1 會被 awk 用正規表示法取出的帳號給取代。這裡只是把整個要執行的命令字串設定給 cmd 變數,並未真正的執行

第三行的 print cmd 則是先把命令印出來,並檢視看看是否有寫錯,同時,也可以做為批次執行時的進度顯示。系統管理命令寫錯了,又是批次執行,那可是不得了的。 若沒有確定命令無誤的話,可千萬別把第四行寫進去耶!

第四行的 system(cmd) 則是使用 awk 的 system 函數來執行 cmd 字串的命令。我個人都是先檢視第三行的 print 結果無誤之後才寫這一行來執行 awk 做批次命令。

第五行 /etc/passwd 一定是一個文字檔, awk 會依照正規表示式逐筆搜尋符合的資料,並按 FS 的 awk 內建變數指定的分隔字元將每筆資料分割成 $1、$2… 的變數來使用。

透過這樣的型式,舉凡批次建帳號(用 useradd )、批次改密碼(用 passwd )、批次刪除帳號(用 userdel )、批次改帳號的有效期限(用 chage)都可以套用這個型式輕鬆的處理。

最後,應該有人會質疑,第二行裡面不是把每個人的密碼都設成 newpassword 了嗎?啊哈!別傻了,我怎麼會把密碼設的如此白癡還公告在這裡?

下面是 awk 的一些相關連結:

1 則留言: