日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

awk文本处理总结

發(fā)布時(shí)間:2023/12/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 awk文本处理总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
awk文本處理總結(jié)(入門,中級,高級) 轉(zhuǎn)載:
?http://blog.chinaunix.net/u/5591/showart.php?id=481458

?
awk處理文本總結(jié) - Alex.Wang??????????? 2008-2-19 15:55
???
???
??? 作為技術(shù)支持工程我們最最經(jīng)常的工作就是經(jīng)常碰到要處理文本文件,不管是什么數(shù)據(jù)庫最后都可以導(dǎo)成文本,我們就可以對他進(jìn)行處理了,這樣即使你不是對所有數(shù)據(jù)庫操作都很熟悉也可以對他的數(shù)據(jù)進(jìn)行處理了。
??? 我們必須的工具有兩個(gè)一個(gè)是shell一個(gè)是awk,awk對于處理文本文件是最最適合的掌握了awk我們就可以很方便的處理文本文件再借助一些shell命令我們可以很方便得到自己想要的結(jié)果?,F(xiàn)在從簡單的例子來總結(jié)一下我覺得會(huì)經(jīng)常碰到的問題。
???
??? awk入門篇
???
??? awk入門,文本內(nèi)容example1.txt.
???
user1 password1 username1 unit1 10
user2 password2 username2 unit2 20
user3 password3 username3 unit3 30??
? 在unix環(huán)境中我們可以使用一下命令來打印出第一列
???
[root@mail awk]# awk '{print $1}' example1.txt 得到的結(jié)果是如下,解釋一下"'{" 單引號大括號包含awk語句是為了和shell 命令區(qū)別,$1的意思就是文本文件的第一列,正常的awk命令跟隨-F參數(shù)指定間隔符號,如果是空格或tab鍵就可以省略了。
???
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è)初級的又增加了一個(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è)符號的意義我們才能更好的使用awk,最開始先記住幾個(gè)命令知道他可實(shí)現(xiàn)的結(jié)果我們慢慢的再去理解。
================================================================================ awk中級篇 這里順便介紹一下vi的一個(gè)替換命令,現(xiàn)在我們要把example1.txt文本里的空格都替換為“:”冒號這里在vi里使用的命令就是: %s/ /:/g????? 這個(gè)命令對于使用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 "%s@%s\n",$1,$2}'example2.txt user1@password1 這里的區(qū)別是使用print 和printf的區(qū)別,printf格式更自由一些,我們可以更加自由的指定要輸出的數(shù)據(jù),print會(huì)自動(dòng)在行尾給出空格,而printf是需要給定"\n"的,如果感興趣你可以把“\n”去掉看一下結(jié)果。%s代表字符串%d 代表數(shù)字,基本上%s都可以處理了因?yàn)樵谖谋纠镆磺卸伎梢钥闯墒亲址?#xff0c;不像C語言等其他語言還要區(qū)分?jǐn)?shù)字、字符、字符串等。 awk還有一些很好的函數(shù)細(xì)細(xì)研究一下還是很好用的。
這次碰到了一個(gè)問題客戶有一個(gè)用戶列表,大概有2w用戶,他有一個(gè)有趣的工作要做,就是把每個(gè)賬戶目錄放到特定的目錄下,例如13910011234這個(gè)目錄要放到139/10/這個(gè)目錄下,從這里可以看出規(guī)律是手機(jī)號碼的前三位是二級目錄名,手機(jī)的第3、4為是三級目錄名,我們有的就只有一個(gè)用戶列表,規(guī)律找到了我們現(xiàn)在開始想辦法處理吧。 example3.txt 13910011234?????
15920312343
13922342134
15922334422
...... 第一步是要找到一個(gè)方法來吧,就是要把每一個(gè)手機(jī)號分開,最初可能你就會(huì)想到這個(gè)也沒有任何間隔,我們怎么用awk分開他們呢?說實(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([s])???????????? Returns? the? length? of? the? string s, or the
?????????????????????????????? length of $0 if s is not supplied.
??? length 你可以得到字符串的長度,這個(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
???????????????? described in that man page are available to gawk.????
??????????
??????????????????????????????????????????????????????????????????????????????????
這里舉例說明時(shí)間戳函數(shù)是如何使用的 [root@ent root]# date +%s | awk '{print strftime("%F %T",$0)}'
2008-02-19 15:59:19???????? 我們先使用date命令做一個(gè)時(shí)間戳,然后再把他轉(zhuǎn)換為時(shí)間?????????????????????????????????????????????????????????????????????????????????????????????
還有一些我們現(xiàn)在可能不經(jīng)常用到的函數(shù),詳細(xì)內(nèi)容man awk 自己可以看一下。
?Bit Manipulations Functions?? 二進(jìn)制函數(shù)
?Internationalization Functions? 國際標(biāo)準(zhǔn)化函數(shù)
?
?USER-DEFINED FUNCTIONS????? 用戶也可以自己定義自己的函數(shù),感興趣自己可以再深入研究一下。
?
? 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è)可能就更高級一些了!
?================================================================================
?awk高級篇
?
?不管學(xué)習(xí)任何語言,我們學(xué)到的都是工具,工具知道的越多,我們做起工作來就越方便,但是工具在你的手里并不一定能造出好的產(chǎn)品,編輯腳本和編程序也是一樣的重要的是算法,別人不知道怎么處理的問題你要知道如何處理。這才能證明你比別人更高,工具只要你慢慢練習(xí)都會(huì)使用。
?
??? 下面給大家一個(gè)我認(rèn)為是比較高級的問題了,感興趣的可以自己再想想更好的解決辦法。問題是這樣的我們有一個(gè)從ldap里導(dǎo)出的文件,它都是一行一個(gè)字段來說明的,每個(gè)用戶的數(shù)據(jù)是已空行分割的。我們必須把對應(yīng)的uid 和userPassword找出來而且是對應(yīng)的。
???
??? 例子:example4.txt
????
dn: uid=cailiying,domain=ccc.com.cn,o=mail.ccc.com.cn
uid: cailiying
userPassword:: e21kNX0zREl4VEIwODBJdXZkTnU3WFFtS3lRPT0=
letters: 300
quota: 100
dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
letters: 300
quota: 100
uid: chenzheng
domain: cqc.com.cn
dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
letters: 300
quota: 100
dn: uid=caixiaoning,domain=ccc.com.cn,o=mail.ccc.com.cn
userPassword:: e21kNX1kejFXU0doZWprR2RNYnV5ajJJRWl3PT0=
letters: 300
quota: 100
uid: chenzheng
domain: cqc.com.cn
處理這個(gè)文本我們需要考慮的問題是:
1 uid? 和userPassword 并不是每一個(gè)段落里都有
2 在每一段里面uid和userPassword 先后順序是隨機(jī)的
3 有的段落里可能只有uid 或者只有userPassword 從文本上分析可以看出必須使用的間隔符號,一個(gè)是空行,一個(gè)是冒號。
冒號我們awk -F:就可以了,不過空行我們不好判斷現(xiàn)在想到length()這個(gè)函數(shù),在unix里空行最多只有一個(gè)\n字符,如果一行字符數(shù)小于2我們判斷為空行,好現(xiàn)在間隔符號問題解決,空行只能通過循環(huán)來實(shí)現(xiàn)對空行的判斷。???????????????????????????????????????? 現(xiàn)在碰到的另外一個(gè)問題是我們的某個(gè)段里的信息是不完全的,我們就要放棄這段這兒如何來做,就是要做兩個(gè)標(biāo)記變量u 和 p? 再做一個(gè)循環(huán)如果u? 和? p 同事滿足我們才輸出結(jié)果下面的awk腳本就是通過這個(gè)思考來解決ldif文本的處理的! # 此腳本的目的是方便我們以后導(dǎo)ldap的其他郵件的數(shù)據(jù),
# 我們之前使用slapdcat -l 導(dǎo)出所有信息,然后我們需要
# 整理出uid? password , 這里的設(shè)置都是默認(rèn)以":" 間隔的
# 例slapcat -l user.ldif? 如果想得到一份uid 和userPassword 對應(yīng)的文件,
# 修改username = "dn"; password = "userpassword"; awk -f ldap2txt.awk user.ldif | grep uid | more? 可以查看結(jié)果 (有可能是多域的郵件)
# 如果想得到domain 所對應(yīng)的密碼,修改 username = "dn"; password = "userpassword";? 運(yùn)行 awk -f ldap2txt.awk user.ldif |grep domain | more
#!/bin/awk -f
# File name: ldap2txt.awk
BEGIN {
??????? FS = ":";
??????? username = "uid";
??????? password = "userPassword";
}
{ ??????? if(length($0) == 0 )
??????? {
??????????????? if (name != "u"? &&? pword != "p")
??????????????? {
??????????????????????? printf ("%s:%s\n", name,pword);
??????????????????????? name = "u";
??????????????????????? pword = "p";
??????????????? }
??????? }
??????? else?
??????? {
??????????????? if ($1 == username)
??????????????? {
??????????????? name = "u";
??????????????? name = $0;
??????????????? }
??????????????? else if($1 == password)
??????????????? {
??????????????? pword = "p";
??????????????? pword = $0;
??????????????? }
??????? }
}
END {
} 實(shí)際上對于學(xué)習(xí)語言首先是熟悉一些常用的函數(shù),然后就是試著去解決別人解決過的問題,然后自己再思考一下是不是有更好,速度更快的解決辦法,實(shí)際上大部分的程序員都是在重復(fù)的使用著別人好的解決辦法,把別人的方法轉(zhuǎn)變?yōu)樽约旱姆椒?#xff0c;就是反復(fù)練習(xí)解決不同的問題,思考更好的方法!???????????????
?

轉(zhuǎn)載于:https://blog.51cto.com/gavinshaw/175033

總結(jié)

以上是生活随笔為你收集整理的awk文本处理总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。