0、前言
awk、grep、sed是linux文本操作的三大利器,grep适合单纯的查找或文本匹配,sed适合编辑匹配到的文本,awk适合格式化文本,对文本进行较复杂格式处理。
1、grep文本查询
命令格式:grep [option] pattern file 用于过滤/搜索的特定字符,可与正则表达式配合,使用上十分灵活。

2、sed文本编辑
命令格式:sed [options] '[地址定界] command' file(s) 用于编辑一个或多个文件, 简化对文件的反复操作。
演示实例:
[root@along ~]$ cat demo
aaa
bbbb
AABBCCDD
[root@along ~]$ sed -n "/aaa/p" demo #-n 打印匹配的行
aaa
[root@along ~]$ sed -e "s/a/A/" -e "s/b/B/" demo #-e多点编辑
Aaa
Bbbb
AABBCCDD
[root@along ~]$ sed "1~2s/[aA]/E/g" demo #将奇数行的a或A替换为E
EEE
bbbb
EEBBCCDD
[root@along ~]$ sed -n "1,2p" demo #打印1-2行
aaa
bbbb
[root@along ~]$ sed "2s/b/B/g" demo #替换第2行的b->B
aaa
BBBB
AABBCCDD
[root@along ~]$ sed "2d" demo #删除第2行
aaa
AABBCCDD
[root@along ~]$ sed "2a123" demo #在第2行后加123
aaa
bbbb
123
AABBCCDD
[root@along ~]$ sed "1i123" demo #在第1行前加123
123
aaa
bbbb
AABBCCDD
[root@along ~]$ sed "3c123\n456" demo #替换第3行内容
aaa
bbbb
123
456
[root@along ~]$ sed -n "3w/root/demo3" demo #保存第3行的内容到demo3文件中
[root@along ~]$ sed "1r/root/demo3" demo #读取demo3的内容到第1行后
aaa
AABBCCDD
bbbb
AABBCCDD
[root@along ~]$ sed 's@[a-z]@\u&@g' demo #将全文的小写字母替换为大写字母
AAA
BBBB
AABBCCDD
[root@along ~]$ sed -i.bak "s/a/A/g" demo #-i 在文件直接替换a为A,并保持原文件到.bak后缀
[root@along ~]$ cat demo
AAA
bbbb
AABBCCDD
3、awk文本格式化
命令格式:awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ... 用于在linux下对文本和数据进行处理,数据可以来自一个或多个文件,支持用户自定义函数和动态正则表达式等功能。
演示实例:
[root@along ~]$ cat awkdemo
hello:world
linux:redhat:lalala:hahaha
along:love:youou
[root@along ~]$ awk -v FS=':' '{print $1,$2}' awkdemo #FS指定输入分隔符
hello world
linux redhat
along love
[root@along ~]$ awk -v FS=':' -v OFS='---' '{print $1,$2}' awkdemo #OFS指定输出分隔符
hello---world
linux---redhat
along---love
[root@along ~]$ awk -v RS=':' '{print $1,$2}' awkdemo #按分隔符截取,不区分行
hello
world linux
redhat
lalala
hahaha along
love
you
[root@along ~]$ awk -v FS=':' -v ORS='---' '{print $1,$2}' awkdemo #按分隔符截取,用指定符号连接
hello world---linux redhat---along love---
[root@along ~]$ awk -F: '{print NF}' awkdemo #按分隔符计数
2
4
3
[root@along ~]$ awk -F: '{print $(NF-1)}' awkdemo #显示倒数第2列
hello
lalala
love
[root@along ~]$ awk '{print NR}' awkdemo awkdemo1
1
2
3
4
5
[root@along ~]$ awk END'{print NR}' awkdemo awkdemo1
5
[root@along ~]$ awk '{print FNR}' awkdemo awkdemo1
1
2
3
1
2
[root@along ~]$ awk '{print FILENAME}' awkdemo
awkdemo
awkdemo
awkdemo
[root@along ~]$ awk 'BEGIN {print ARGC}' awkdemo awkdemo1
3
[root@along ~]$ awk 'BEGIN {print ARGV[0]}' awkdemo awkdemo1
awk
[root@along ~]$ awk 'BEGIN {print ARGV[1]}' awkdemo awkdemo1
awkdemo
[root@along ~]$ awk 'BEGIN {print ARGV[2]}' awkdemo awkdemo1
awkdemo1
a.随机取用户
cat file1 | awk '{ print rand(),$1 }' |sort -k1 |awk '{ print $2 }' |head -4000
b.分组求和
awk '{s[$1] += $2}END{ for(i in s){ print i, s[i] } }' file1 > file2
c.求和
cat data|awk '{sum+=$1} END {print "Sum = ", sum}'
d.求平均
cat data|awk '{sum+=$1} END {print "Average = ", sum/NR}'
e.求标准偏差
cat $FILE | awk -v ave=$ave '{sum+=($1-ave)^2}END{print sqrt(sum/(NR-1))}'
f.列换成行,如果第一列相同,将所有的第二列 第三列 都放到一行里面
awk '{qq[$1]=qq[$1](" "$2" "$3)}END{for(i in qq)print i,qq[i]}'
g.合并文件,2个文件,每个2列,将他们按照第一列相同的数,来合并成一个三列的文件,同时,将每个文件中针对第一列对应第二列中没有的数补0
awk 'FNR==NR{a[$1]=$2}FNR<NR{a[$1]?a[$1]=a[$1]" "$2:a[$1]=a[$1]" 0 "$2}END{for(i in a)print i,a[i]}' file1 file2 > file3
网友评论