|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
按照它们在系统中的作用分成几个部分介绍给大家,通过这些基础命令的学习我们可以进一步理解Linux系统:
在我还读研讨生时,我被一个我曾同事过的传授向我展现的崇高高贵文本文件操纵才能震动了,因而我决意花点工夫学学他用来操纵文本文件的神器Awk。
即使是在明天,我所熟悉的90%的程序员几近从没用过awk,实在只需你花上几分钟懂得哪怕只是awk10%的语法,它都能梦境般的进步你操纵文本文件的才能。上面就让我来教你一些最有效的操纵——注重,不是“最基本的”,只需你乐意花上5分钟工夫实习下这些技能,我信任你就将会意会到我以为这门言语最为风趣的工具。
Awk实践上是一门十分风趣的小型编程言语,它计划的次要目标就是为了处置字符串。还记得有次我们的一个传授为我们安排了一道盘算机收集的课程功课,让我们依据RPC协定编写一个能够天生客户端和服务端stub的程序,可是这个传授犯了一个毛病,他告知我们可使用任何我们想要的言语,因而我决意用Awk来写一个,我底本的目标只是为了更好的把握Awk,可是让我惊异的是,我发明终极我的完成要比别的我用过的言语(Python,C++,Java)都更冗长。
假如要懂得Awk,你能够看看这本书,固然我已看过了,可是你大概其实不想像我那样用Awk来完成某个协定的一个剖析器,也许你只是想从你的日记文件中找出那些IP地点加起来恰好是666的家伙,那就跟我来吧,持续往下看!
让我们先来看个例子,假定我们有一个小文件(logs.txt)看起来像是上面如许,很复杂,它只要2行带有IP地点的log信息:
07.46.199.184[28/Sep/2010:04:08:20]"GET/robots.txtHTTP/1.1"2000"msnbot"
123.125.71.19[28/Sep/2010:04:20:11]"GET/HTTP/1.1"304-"Baiduspider"
这是两条由Apache天生的日记信息,很复杂,它们显现了Bing和Baidu的爬虫今天到访过我的网站。
Awk同别的命令路程序(好比grep)一样,都是从stdin读取输出并写到stdout,以是你能够很简单的经由过程管道利用它,Awk的利用也很复杂,你独一必要体贴的它令前面的谁人字符串参数:
awk{print$0}
年夜部分awk水平都是以{开首,并以}停止的,{}中包括的命令会在输出中的每行上实行,年夜部分awk程序城市打印些甚么工具,下面的命令会一成不变的将它读到的输出再打印出来,并增加一个换行,$0代表一整行。以是这个程序很典范——它除将输出拷贝到输入,别的甚么都没做。
Awk还会依据输出行中的空缺字符(空格,tab)主动将行切分为字段,并主动处置连着的分开字符,你能够经由过程$1,$2,$3等来援用支解后的字段。
echothisisatest|awk{print$3}//printsa
awk{print$1}logs.txt
输入:
07.46.199.184
123.125.71.19
很复杂,而且很有效,不是吗?可是偶然我必要从字符串的开头入手下手打印,这时候我可使用一个名为NF的特别变量,它包括了以后行的字段数,因而我可使用$NF来打印最初一个字段,我也能够经由过程这个值来反向查找某个字段,同时我还能够在一行打印多个值:
echothisisatest|awk{print$NF}//prints"test"
awk{print$1,$(NF-2)}logs.txt
输入:
07.46.199.184200
123.125.71.19304
更进一步——如今你能够看到,我们能够将日记文件支解,并只打印我们体贴的部分。另外一个很有效的变量就是NR,这个变量暗示以后正在处置的输出的行号。在我演示NR的同时,我还想展现一下怎样利用print来格局化输入,你可使用逗号来分开print的多个参数,它们会被转化为空格,可是上面的例子我没有利用逗号,以是了局中也没有拔出空格:
awk{printNR")"$1"->"$(NF-2)}logs.txt
输入:
1)07.46.199.184->200
2)123.125.71.19->304
很壮大,而且一点也不难,对吧,假如你喜好,你还可使用printf函数,也许你对它更熟一些。如今,成绩来了,不是一切字段都是以空格作为分开符的,好比上面这个:
$awk{print$2}logs.txt
输入:
[28/Sep/2010:04:08:20]
[28/Sep/2010:04:20:11]
日期字段利用了/和:作为分开符,固然我能够经由过程一条awk命令来完成这个操纵,可是我想向你演示一种更复杂也是你更加熟习的体例:Unix管道,上面我要做的就是经由过程管道利用别的一条awk命令来依据冒号对日期举行支解,要做到这一点,我的第二个awk命令必要利用2个{},不外我临时不想对这个多做注释,你只需看看我是怎样做的就好了:
$awk{print$2}logs.txt|awkBEGIN{FS=":"}{print$1}
输入:
[28/Sep/2010
[28/Sep/2010
我为FS(也就是字段分开符)指定了一个分歧的值,也就是":",然后打印出了第一个字段,如今没偶然间了,只要日期!假如你不想看到输入中的谁人[,最复杂的办法就是利用sed,也许你早就晓得了:
$awk{print$2}logs.txt|awkBEGIN{FS=":"}{print$1}|seds/[//
输入:
28/Sep/2010
28/Sep/2010
利用不异的技能,我还能够进一步依据/‘字符来切分日期,可是我以为你已把握这个技能了,以是我就不罗嗦了,上面,让我们来试着到场一点点逻辑判别,假如我只想失掉形态为200的行,我可使用grep,可是假如我想失掉IP地点中包括200的行,大概是日期在2000年今后的行,那我就必要先利用awk,然后在经由过程grep来查找了,不外的成绩是输入了局没了高低文,还好,Awk撑持if前提判别,以是我们能够像上面如许:
$awk{if($(NF-2)=="200"){print$0}}logs.txt
输入:
07.46.199.184[28/Sep/2010:04:08:20]"GET/robots.txtHTTP/1.1"2000"msnbot"
如今,只要切合前提的行才会被输入,这个if语句其实是太熟习不外了,应当不必要我做过量的注释,上面让我经由过程一个蠢例子向你演示下awk怎样完成跨行保留形态,假定我想失掉这个文件中一切HTTP响应的形态字段的和,固然我其实想不出有有甚么来由如许做,可是为了演示字段乞降,就让我们先忘记这一点吧,要做到这一点,我只必要创立一个变量就okay了:
$awk{a+=$(NF-2);print"Totalsofar:",a}logs.txt
输入:
Totalsofar:200
Totalsofar:504
很明显,这是有成绩的,年夜部分情形下,我其实不必要两头值,只必要最初的了局就能够了,固然我可使用tail-n1,可是另有一种更好的体例,我可使用END关头字告知awk只在最初一行挪用print:
$awk{a+=$(NF-2)}END{print"Total:",a}logs.txt
输入:
Total:504
假如你想要懂得更多关于awk的常识,有几本好书和大批的线上资本可供你参考,只必要花上一些空闲工夫,你就能够很简单的学到关于awk的统统,可是要纯熟利用它,仍是有些应战的,由于它的编码体例其实有点出格——你实践上是在写一个for轮回的外部完成,细心想一想,这实在有点MapReduce的感到,只是一入手下手会让人有些利诱。
我但愿这篇文章能对你有效,假如你以为它有效,无妨给我留言。
更新:这篇文章的很多批评都很值得一读,固然我很但愿它们都能在一个中央,但如今我只能把它们分离列出来:
ProgrammingReddit
HackerNews
最初,假如你是那种对awk感乐趣的人,毫无疑问,你就是那种我但愿能够在Google同事的人,假如你感乐趣,能够给我简历(ggrothau@gmail.com),我能够确保它必定会呈现在符合的雇用者眼前,而不是遗落在我们天天收到的那一年夜堆简历中。
学习python,无论你是打算拿他当主要开发语言,还是当辅助开发语言,你都应该学习他,因为有些时间我们耗不起。 |
|