user1
user2
user3
[root@mail awk]# awk '{if($5>20) {print $1}}' example1.txt
這行命令和上一行比較增加了“if($5>20)”,得到的結(jié)果是
user3
這個(gè)if語句就沒有必要更詳細(xì)的解釋了吧!就是第5列大于20的顯示出滿足條件的第一列
[root@mail awk]# awk '{if($5>20 || $5==10) {print $1}}' example1.txt
user1
user3
在來一個(gè)初級(jí)的又增加了一個(gè)“if($5>20 || $5==10)” 做邏輯判斷邏輯判斷的三個(gè)“|| &&
!”
或、與、非三個(gè)可以任意加到里面,這個(gè)語句的意思是如果第5列大于20或者等于10的都顯示處理,在我們的工作中可能有用戶會(huì)要求找出所有空間大于多少的
或者是空間等于多少的賬戶然后再做批量修改。
if是awk循環(huán)中的一個(gè)還有其他很多,man awk可以看到,
Control Statements
The control statements are as follows:
if (condition) statement [ else statement ]
while (condition) statement
do statement while (condition)
for (expr1; expr2; expr3) statement
for (var in array) statement
break
continue
delete array[index]
delete array
exit [ expression ]
{ statements }
學(xué)習(xí)awk可以經(jīng)常使用一下man awk 可以看到所有的函數(shù)和使用方法。
了解每個(gè)符號(hào)的意義我們才能更好的使用awk,最開始先記住幾個(gè)命令知道他可實(shí)現(xiàn)的結(jié)果我們慢慢的再去理解。
================================================================================
awk中級(jí)篇
這里順便介紹一下vi的一個(gè)替換命令,現(xiàn)在我們要把example1.txt文本里的空格都替換為“:”冒號(hào)這里在vi里使用的命令就是:
%s/ /:/g
這個(gè)命令對(duì)于使用vi的人來說是用得最多的。我們現(xiàn)在做了一個(gè)新的文件example2.txt。
user1:password1:username1:unit1:10
user2:password2:username2:unit2:20
user3:password3:username3:unit3:30
現(xiàn)在我們來做一個(gè)awk腳本,之前都是在命令行操作,實(shí)際上所有的操作在命令行上是可以都實(shí)現(xiàn)的,已我們最經(jīng)常使用的批量添加用戶來開始!script1.awk
#!/bin/awk -f # 當(dāng)文件有可執(zhí)行權(quán)限的時(shí)候你可以直接執(zhí)行
# ./script1.awk example2.txt
# 如果沒有以上這行可能會(huì)出現(xiàn)錯(cuò)誤,或者
# awk -f script1.awk example2.txt 參數(shù)f指腳本文件
BEGIN { # “BEGIN{”是awk腳本開始的地方
FS=":"; # FS 是在awk里指分割符的意思
}
{ # 接下來的“{” 是內(nèi)容部分
print "add {"; # 一下都是使用了一個(gè)awk函數(shù)print
print "uid=" $1;
print "userPassword=" $2;
print "domain=eyou.com" ;
print "bookmark=1";
print "voicemail=1";
print "securemail=1"
print "storage=" $5;
print "}";
print ".";
} # “}” 內(nèi)容部分結(jié)束
END { # “END{” 結(jié)束部分
print "exit";
}
執(zhí)行結(jié)果
[root@mail awk]# awk -f script1.awk example2.txt
add {
uid=user1
userPassword=password1
domain=eyou.com
bookmark=1
voicemail=1
securemail=1
storage=10
}
.
.
.
.
.
.
exit
文本操作就是更方便一些。
下面給兩個(gè)返回效果一樣的例子
[root@mail awk]# awk -F: '{print $1"@"$2}' example2.txt
[root@mail awk]# awk -F: '{printf "
[email=%s@%s%5Cn%22,$1,$2%7D%27]%s@%s\n",$1,$2}'[/email]
example2.txt
[email=user1@password1]user1@password1[/email]
這里的區(qū)別是使用print
和printf的區(qū)別,printf格式更自由一些,我們可以更加自由的指定要輸出的數(shù)據(jù),print會(huì)自動(dòng)在行尾給出空格,而printf是需要給定"
\n"的,如果感興趣你可以把“\n”去掉看一下結(jié)果。%s代表字符串%d
代表數(shù)字,基本上%s都可以處理了因?yàn)樵谖谋纠镆磺卸伎梢钥闯墒亲址,不像C語言等其他語言還要區(qū)分?jǐn)?shù)字、字符、字符串等。
awk還有一些很好的函數(shù)細(xì)細(xì)研究一下還是很好用的。
這次碰到了一個(gè)問題客戶有一個(gè)用戶列表,大概有2w用戶,他有一個(gè)有趣的工作要做,就
是把每個(gè)賬戶目錄放到特定的目錄下,例如13910011234這個(gè)目錄要放到139/10/這個(gè)目錄下,從這里可以看出規(guī)律是手機(jī)號(hào)碼的前三位是二級(jí)目
錄名,手機(jī)的第3、4為是三級(jí)目錄名,我們有的就只有一個(gè)用戶列表,規(guī)律找到了我們現(xiàn)在開始想辦法處理吧。
example3.txt
13910011234
15920312343
13922342134
15922334422
......
第一步是要找到一個(gè)方法來吧,就是要把每一個(gè)手機(jī)號(hào)分開,最初可能你就會(huì)想到這個(gè)也沒有任何間隔,我們?cè)趺从胊wk分開他們呢?說實(shí)話最初我也考慮
了20多分鐘,后來想起原來學(xué)習(xí)python的時(shí)候有split函數(shù)可以分就想找找awk里是不是有類似的函數(shù),man awk 發(fā)現(xiàn)substr
這個(gè)函數(shù)子串,
[root@mail awk]# awk '{print substr($1,1,3)}' example3.txt
[root@mail awk]# awk '{printf "%s/%s\n",substr($1,1,3),substr($1,4,2)}' example3.txt
[root@mail awk]# awk '{printf "mv %s %s/%s\n",$1,substr($1,1,3),substr($1,4,2)}' example3.txt
以上的兩步的返回自己做一下,最后我們就得到了我們想要的結(jié)果。
mv 13910011234 139/10
mv 15920312343 159/20
mv 13922342134 139/22
mv 15922334422 159/22
把這部分輸出拷貝到一個(gè)shell腳本里,在數(shù)據(jù)當(dāng)前目錄下執(zhí)行就可以了!
substr(s, i [, n]) Returns the at most n-character substring of s
starting at i. If n is omitted, the rest of s
is used.
substr函數(shù)解釋,s代表我們要處理的字符串,i 是我們從這個(gè)字符串的第幾個(gè)位置上開始,n 是我們從開始的位置取多少個(gè)字符。多看看man英文也會(huì)有所提高的。
awk有很多有趣的函數(shù)如果感興趣可以自己去查查看,
man awk
String Functions 字符串函數(shù),舉幾個(gè)覺得常用的函數(shù)
length() Returns the length of the string s, or the
length of $0 if s is not supplied.
length 你可以得到字符串的長(zhǎng)度,這個(gè)是比較常用的一個(gè)函數(shù)
split(s, a [, r]) Splits the string s into the array a on the
regular expression r, and returns the number of
fields. If r is omitted, FS is used instead.
The array a is cleared first. Splitting
behaves identically to field splitting,
described above.
tolower(str) Returns a copy of the string str, with all the
upper-case characters in str translated to
their corresponding lower-case counterparts.
Non-alphabetic characters are left unchanged.
toupper(str) Returns a copy of the string str, with all the
lower-case characters in str translated to
their corresponding upper-case counterparts.
Non-alphabetic characters are left unchanged.
Time Functions 時(shí)間函數(shù),我們最最常用到的是時(shí)間戳轉(zhuǎn)換函數(shù)
strftime([format [, timestamp]])
Formats timestamp according to the specification in format.
The timestamp should be of the same form as returned by sys-
time(). If timestamp is missing, the current time of day is
used. If format is missing, a default format equivalent to
the output of date(1) is used. See the specification for the
strftime() function in ANSI C for the format conversions that
are guaranteed to be available. A public-domain version of
strftime(3) and a man page for it come with gawk; if that
version was used to build gawk, then all of the conversions
For example:
function f(p, q, a, b) # a and b are local
{
...
}
/abc/ { ... ; f(1, 2) ; ... }
DYNAMICALLY LOADING NEW FUNCTIONS 動(dòng)態(tài)加載新函數(shù),這個(gè)可能就更高級(jí)一些了!
================================================================================
awk高級(jí)篇