国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > awk入门学习笔记

awk入门学习笔记

来源:程序员人生   发布时间:2016-07-13 08:52:48 阅读次数:2350次

零、awk的介绍
awk是Linux及Unix操作系统中非常优秀的数据及文本处理工具,它是1种编程语言。
主要用处是自动化运维和文本处理
1、awk基本语法
1、命令行格式:
awk -F' ' '{print $1}' pets.txt
awk -F '{print $1}' pets.txt(由于默许是空格,所以这类情况和上面的等效,但是我在尝试的时候会报错)
-F后面是指定的分隔符,:或' '

awk 'BEGIN{FS=" "}{print $1}' pets.txt
2、文本格式:
#!/usr/bin/awk
BEGIN{ FS=":"}
{print $1}

2、awk的变量
1、经常使用内置变量
$0 当前所有字段
$1~$n 当前第n个字段
FS 分隔符(默许为空格)
NF 字段个数
NR 行号
RS 输入记录的分隔符(默许为空格)

2、RS是指定的换行符,系统默许是\n进行换行,但是如果我们不希望使用\n而是使用自定义的换行符来进行分行,
那末只需要更改RS参数的值便可
awk 'BEGIN{RS=" "}{print $0}' pets.txt

3、NF是列数,如果我们需要打印每行依照我们指定的分隔方法有多少列,可以用以下命令调用
awk -F":" '{print NF}' /etc/passwd----------->输出若干列7,代表文件中每行中以“:”作为分隔符都有7列。

4、NR是行号,如果我们需要给文件的每行加上1个固定的行号格式,例如 "1 : "的情势,可使用以下语句
awk -F' ' '{print NR" : " $0}' pets.txt

5、调用外部变量
awk -v host=$HOSTNAME 'BEGIN{print host}'
也能够自己定义变量名
awk -v host="host" 'BEGIN{print host}'

3、awk的操作符
关系操作符:<、>、<=、>=、==、!=、~ 、!~
1、依照指定要求匹配内容,如果我们需要匹配passwd文件中第7列是以/bin开头的那些行,可以以下表示
awk -F: '$7 ~ /^\/bin/{print $0}' /etc/passwd
冒号分隔 ~代表匹配 ^代表字符串起始标志,匹配内容是/bin(注意后面还要带1个/,否则会报错)
那如果我们需要不匹配/bin开头的行,只需要将~改成!~便可。
上述代码也能够用变量的情势来替换
awk -F: -v reg='^/bin.*' '$7 ~ reg {print $0}' /etc/passwd
用1个正则表达式 reg来代替^/bin.*,然后再匹配第7列符合正则表达式的行并且返回
2、print与printf
如果要打印 /etc/passwd 中的“第1列 : 第2列”这类情势的输出,可以以下操作:
awk -F: '{print $1" : "$2}' /etc/passwd
如果要实现上述功能,可以用printf操作以下:
awk -F: '{printf("%s : %s\n",$1,$2)}' /etc/passwd

4、awk的流程控制
1、条件语句
格式:if(expression) action1;[else action2]
输入1串数字,单数打印no,双数打印yes,可以以下表示
seq 10|awk '{if($0%2==0){print "ok"}else {print "no"}}'
对文件操作,如果/etc/passwd最后1列是以/bin/bash结尾的,那末就打印整行的内容
awk -F: '{if($NF=="/bin/bash"){print $0}}' /etc/passwd
一样可以不写if语句加上1次判断实现1样的功能
awk -F: '$NF=="/bin/bash" {print $0}' /etc/passwd
2、循环语句
格式:while(condition) action
例:如果我们需要给每一个依照分隔符分开的列加上1个列号,如 1:第1列的内容 2:第2列的内容,.......
awk -F: '{i=1;while(i<=NF){printf(" %d:%s",i,$i);i++}{print " "}}' /etc/passwd
一样也能用for循环完成一样的功能
awk -F: '{for(i=1;i<=NF;i++){printf(" %d:%s",i,$i)}{print " "}}' /etc/passwd
例:需要统计最后1列的词出现的频数
awk -F: '{a[$NF]++}END{for(i in a){print i":"a[i]}}' /etc/passwd

3、awk数组
定义1个数组并且打印它
awk 'BEGIN{a[5]="Jack";a["name"]="Lilei";print a[5],a["name"]}'
一样可以用循环来遍历
awk_sed$ awk 'BEGIN{a[5]="Jack";a["name"]="Lilei";for(i in a)print i":"a[i]}'

netstat -an | awk '/^tcp/{state[$NF]++}END{for(key in state){print key"\t"state[key]}}'
5、awk函数
1、算术函数
awk的算术函数、字符串函数
int(x) 返回x的整数部份的值
sqrt(x) 返回x的平方根
rand() 返回伪随机数r,其中0<=r<1
sand(x) 建立rand()新的种子数。如果没有指定就用当天的时间。
随机数示例:
awk 'BEGIN{print rand();srand();print rand()}'
2、字符串函数
sub(),gsub() 替换函数
index(s,t) 返回子串t在字符串s中的位置,如没有则返回0。
length(s) 返回字符串长度,当没有给出s时,返回$0的长度。
match(s,r) 如果正则表达式r在s中匹配到,则返回出现的起始位置,否则返回0
split(s,a,sep) 使用sep将字符串s分解到数组a中。默许sep为FS。
tolower(s) 将字符串s中的所有大写字符转换为小写。
toupper(s) 将字符串s中的所有小写字符转换为大写。
例:替换字符串中的某个单词。将world换成China,
echo "hello world world" | awk '{sub("world","China");print $0}'
输出: hello China world

上例只是替换了1个world,用gsub可以将所有的都进行替换
echo "hello world world" | awk '{gsub("world","China");print $0}'
输出:hello China China

查找子串的位置
echo "hello world world" | awk '{print index($0,"world")}'

用指定分隔符分隔字符串
echo "00⑴1⑵2⑶3⑷4" |awk '{split($0,a,"-");for(i in a){print i":"a[i]}}'

3、自定义函数
自定义加法
awk 'function sum(n,m) {total=n+m;return total} BEGIN{print sum(1,2)}'

6、1些经常使用的操作
1、获得本机的ip地址
ifconfig eth0 | awk -F':| +' '/inet addr:/{print $4}'
2、统计网络连接数
netstat -an | awk '/^tcp/{state[$NF]++}END{for(key in state){print key"\t"state[key]}}' | column -t
3、在做训练集的时候需要统计不同种别的散布的时候,可以有以下办法(假定label放在最后,个人习惯):
cat test.txt | awk '{count[$NF]++}END{for(key in count){print key"\t"count[key]}}' | sort -k2 -n -r
awk '{print $NF}' test.txt | sort | uniq -c | sort -nr
test.txt的最后1列是label,统计它的label
4、将文件最后1列去掉
awk '{$NF="";print $0 >>"test.txt"}' 51job.txt




生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生