awk推荐去看朱双印的博客“awk从放弃到入门”,写的真的很好,本文的awk就总结于它。html
awk实际上是一门编程语音,它支持条件判断、数组、循环等功能。因此,咱们也能够把awk理解成一个脚本语言解释器node
awk 【option】 ‘program’ file1,file2linux
1) BEGIN和END模块只能有一个。中间的pattern匹配,能够有多个git
NR==2{print $1}NR==5{print $1}正则表达式
2) BEGIN模块,表明awk在处理文本前要作的事。即便不接收文件名,仅仅使用BEGIN模块打印,也能正常输出shell
awk ‘BEGIN {print “111”,”222”}’编程
3) END模块,表明awk在处理文本后要作的事数组
awk ‘{print $1,$2} END{print ‘333’,’444’}’test缓存
变量名编辑器 |
属性 |
备注 |
$0 |
当前记录。即一整行 |
|
$1~$n |
当前记录的第n个字段 |
awk ‘{print “str:”$1}’ |
FS |
输入字段分隔符,默认space |
awk –F ‘:’ awk –v FS=’:’ |
RS |
输入记录分隔符,默认为\n |
若是RS=””,会以空白行分隔 |
OFS |
输出字段分隔符,默认space |
|
ORS |
输出的记录分隔符,默认\n |
|
NF |
当前记录中的字段个数,即多少列 |
|
NR |
行号,从1开始 |
|
FNR |
各文件分别显示行号 |
|
FILENAME |
当前文件名 |
awk ‘{print FILENAME,$0}’ |
ARGC |
命令行参数的个数 |
|
ARGV |
数组,保存的是命令行所给定的参数 |
ARGV[0]是awk,单引号中的不算参数,处理的文件是参数 |
awk除了使用内置变量,还能够本身定义变量。
方法一:-v varname=value 变量名区分字符大小写。-v:设置变量
方法二:在program中定义
1、-v 定义
2、在program定义
awk自己负责文本切割,printf动做则负责格式格式化文本。在了解awk的printf动做前,须要首先了解printf命令
在shell中,echo和printf都是输出文本的命令。echo输出的字符串,会自动在末尾加上\n,
而printf不会。printf的做用是按照咱们指定的格式输出文本,因此\n,也须要咱们本身指定
注意看3,printf的优点就在于,能够用格式替换符,帮咱们处理一长串的str
名称 |
含义 |
%s |
字符串 |
%f |
浮点格式 |
%b |
对应的参数包含转义字符时,对应的转义字符会被转义 |
%c |
ASCII字符,显示对应参数的第一个字符 |
%d,%i |
十进制整数 |
%o |
不带正负号的八进制值 |
%u |
不带正负号的十进制值 |
%x |
不带正负号的十六进制值,用a到f表示10至15 |
%X |
不带正负号的十六进制值,用A到F表示10至15 |
%% |
表示‘%’自己 |
名称 |
含义 |
\a |
警告字符,常为ASCII的BEL字符 |
\b |
后退 |
\c |
不显示输出结果中任何结尾的换行字符(%b格式下的参数字符串依然有效) |
\f |
换页(formfeed) |
\n |
换行 |
\r |
回车 |
\t |
水平制表符 |
\v |
垂直制表符 |
\\ |
“\”自己 |
\ddd |
表示1到3位数八进制值得字符串,仅在字符格式串中有效 |
\0ddd |
表示1到3位数八进制值得字符串 |
参数 |
含义 |
%7s |
7就表明当前替换符对应的输出长度为7个字符宽,不足补齐,超出也正常显示 |
%-7s |
“-”,表示左对齐,不加时,是右对齐 |
%+5d |
正数会自动变为+num |
%12.3f |
“.3”表示保留小数点后三位,%f默认是小数点后6位 |
%12.5d |
“.5”表示整数的长度,不足用0补齐 |
awk的printf动做与shell的printf命令很像,只是要注意几点:
1) 使用printf动做输出的文本不会换行,要本身手动加\n
2) 使用printf动做时,“指定的格式”与“被格式化的文本”间,要用“逗号”隔开
3) 使用printf动做,“格式替换符”与“被格式化的文本”数量一一对应
例子
awk -v FS=':' 'BEGIN{printf "%-10s\t %s\n","用户名称","用户ID"} {printf "%-10s\t %s\n",$1,$3}' /etc/passwd
用户名称 用户ID
root 0
bin 1
grep ‘^root’/etc/passwd
awk ‘/^root/{print $0}’ /etc/passwd
1)awk命令中的正则是“扩展正则表达式”
2)当使用{x,y}或[[:space]],这种正则时,要加上参数—posix
3)注意对“\”和“.”转义
两个正则的就是行范围模式,从正则1匹配的行开始,到正则2匹配的行结束
正则匹配符
~ |
匹配后面的正则。’$1~/pattern/’ |
!~ |
不匹配后面的正则’$1!~/pattern/’ |
上图的动做分为两个部分:
1) 红线标注:最外侧的括号“{}”。“组合语句”类型的动做,将多个代码组合成代码块
2) 蓝线标注:“print $0”。print是“输出语句”类型的动做
例子
若是if对应的{},只有一条命令,能够省略{}
do…while循环不管是否知足while的条件,都会先执行一次do里的命令
# 打印一遍test
# 打印5遍test
# 1~5,不打印3
# 打印1~3
awk中,exit表示跳事后序全部动做,直接执行END内的命令。若是没有END模式,则会直接结束awk命令
# 只打印1
# 不会打印$0
next的做用是跳过当前行。直接从下一行 开始处理
# 跳过第2行
1)awk中的数组是一个使用字符串做为下标的“关联数组”。
2)咱们在使用时,能够用 数字/字符串 做为下标,不过使用数字做为下标时,awk默认会把“数字”下标转换为“字符串”。
3)在awk中,元素的值能够设置为“空”。
4)当一个元素不存在于数组时,若是咱们直接引用这个不存在的元素,awk会自动建立这个元素,而且默认为这个元素赋值为“空字符串”
5)在awk中,判断数组中元素是否存在,用“if(下标 in 数组名)”。即判断数组中是否有key
6)使用split函数生成的数组,下标默认是从1开始的
# 建立数组,直接建立就能够
# 删除数组中的元素
awk ‘BEGIN{ …;delete huluwa[0]}’
# 删除整个数组
awk ‘BEGIN{ …;delete huluwa}’
# for循环有序遍历数组。只有下标是数字时,经过下标的递增,才能有序遍历
awk ‘BEGIN{ …;for (i=1;i<=3;i++){print i,huluwa[i];} }’
# for循环无序遍历数组。由于awk数组自己是无序的关联数组
awk ‘BEGIN{ …;for (i in huluwa){print i,huluwa[i]} }’
# 实例应用——统计某文件$1 重复出现的次数
awk ‘{count[$1]++} END{ for (i in count ) {print i,count[i]} }’ file
# 实例应用——统计某文本人名出现次数
awk ‘{ for (i=1;i<=NF;i++) {count[$i]++} } END{ for (a in count) {print a,count[a]} }’
rand函数固定打印了0.237788,srand函数固定打印1,二者合用,可生成小于1的随机数
# rand函数
awk 'BEGIN{print rand()}'
0.237788
# srand函数
awk 'BEGIN{print srand()}'
1
# 生成小于1的随机数
awk 'BEGIN{srand();print rand()}'
0.319498
# 经过随机数乘100,在经过int函数取整,生成0~100间的随机数
awk 'BEGIN{srand();print int(100*rand())}'
76
这两个函数用于替换某些 文本
awk ‘{ gsub (“old”,“new”,$1);print $0}’file
awk ‘{ gsub (“[a-z]”,“new”,$1);print $0}’file
gsub将指定范围内匹配的字符所有替换为新字符
sub用法与gsub同样,但只替换匹配范围内第一次匹配到的字符
# 好比某文件就一行,$1=aaa。
gsub(“a”,“b”),则$1=bbb。第三个参数不加,则默认为$0
sub(“a”,“b”),则$1=baa。
length函数可获取指定字符串的长度。不指定参数,默认为$0
awk ‘{ for (i=1;i<=NF;i++) {print $i,length($i)} }’file
获取指定字符串位于整个字符串中的位置
awk ‘{print index($0,“LEE”)}’file
0
7
0
index函数在每一行中查找LEE,若是该行没有,返回0,该行有,返回位置
split函数能够切割字符串,帮咱们动态生成数组。生成的数组下标从1开始
# 将ts以“;”分隔,并将分隔后的str保存到huluwa数组中
awk –v ts=”one;two;three”‘BEGIN{ print split(ts,huluwa,”;”)}’
# split函数的返回值就是数组长度
split(ts,huluwa,”;”) == 3
asort函数根据数组的value值进行排序
# asort排序后,原有key将被数字替代
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35 ; asort(t) ; for (i in t){print i,t[i]} }'
1 35
2 66
3 88
# asort排序时,新建一个数组。t[]不变,新创了new[]
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35 ; asort(t,new) ; \
for (i in new){print i,new[i]} }'
# asort函数的返回值就是数组的长度
asort(t,new)==3
asorti函数会对原数组的key排序,而后将key做为value生成一个新数组
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35;asorti(t,new);for (i in new){print i,new[i]} }'
1 a
2 b
3 c
# 经过asorti排列原数组
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35;asorti(t,new);\
for (i in new){print i,new[i],t[new[i]] } }'
1 a 66
2 b 88
3 c 35
# if…else判断用户类型
awk –F : ‘{ if($3<500){usertype=“系统用户”}else{ usertype=“普通用户”};\
print $1,usertype }’/etc/passwd
# 三元运算符替换if…else
awk –F : ‘{ usertype=$3<500?“系统用户”: “普通用户”;\
print $1,usertype }’/etc/passwd
l $3<500:条件判断
l ?”系统用户”:为真,则“系统用户”赋给usertype
l :“普通用户”:为假,则“普通用户”赋给usertype
# 三元运算符统计“系统用户”和“普通用户”数量
awk -F: '{$3<500?a++:b++}END{print a,b}' /etc/passwd
# 打印奇数行
awk ‘a=!a’flie
# 打印偶数行
awk ‘!(a=!a)’flie
解析:
咱们知道awk的正则匹配是
/
但若是咱们不加print动做,仅仅有正则,那么会默认打印$0。
awk ‘/正则/’file
而在awk中,非0/非空str表示“真”。0/空表示“假”
# 注意,这不是正则,‘2’不为0/空,打印file全部
awk '2' file
因此’a=!a’
1) a没有定义,初始化a=‘’,a为“假”
2) !a为“真”
3) a=!a,a变为“真”,打印第1行
4) !a又变为“假”,不打印第2行
‘!(a=!a)’
1)a=!a为真,!(a=!a)为假,不打印 第1行
2)a=!a为假,!(a=!a)为真,打印第2行
awk从放弃到入门 (http://www.zsythink.net/?s=awk)
awk用法(使用入门) (http://www.javashuo.com/article/p-yqjjrswt-da.html)
官方文档 (https://www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents)
sed命令是一个面向字符流的非交互式编辑器,按行来处理文本内容。在shell中,使用sed来批量修改文本内容是很是方便的。
sed 把每一行都存在临时缓存区中,对这个副本进行编辑,因此不会修改或破坏源文件。具体过程以下:
1)sed 把当前正在处理的行保存在一个临时缓存区中,这个缓存区称为“模式空间”或“临时缓冲”。
2)sed 对模式空间中的行后处理完毕后,就把该行发送到屏幕上(除非以前有命令删除这一行或取消打印操做)。
3)sed处理完输入文件的最后一行后, sed 便结束运行。
sed的命令格式
sed [option] 'sed command'filename
sed的脚本格式
sed [option] -f 'sed script'filename
-n :使用安静(silent)模式。在通常 sed 的用法中,全部来自 STDIN 的数据通常都会被列出到终端上。但若是加上 -n 参数后,则只有通过sed 特殊处理的那一行(或者动做)才会被列出来。
-e :多重编辑,且命令顺序会影响结果
-f :直接将 sed 的动做写在一个文件内, -f filename 则能够运行 filename 内的 sed 动做;
-r :sed 的动做支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。
x |
x为行号 |
x,y |
表示行号从x到y |
/pattern |
查询包含模式的行 |
/pattern /pattern |
查询包含两个模式的行 |
pattern/,x |
在给定行号上查询包含模式的行 |
x,/pattern/ |
经过行号和模式查询匹配的行 |
x,y! |
查询不包含指定行号x和y的行 |
命 令 |
说 明 |
a\ |
在当前行后添加一行或多行。 sed ‘/pattern/a new_str’file;sed ‘1a new_str‘ file |
c\ |
用新文本修改(替换)当前行中的文本 |
d |
删除行 |
i\ |
在当前行以前插入文本 |
h |
把模式空间里的内容复制到暂存缓存区 |
H |
把模式空间里的内容追加到暂存缓存区 |
g |
取出暂存缓冲区里的内容,将其复制到模式空间,覆盖该处原有内容 |
G |
取出暂存缓冲区里的内容,将其复制到模式空间,追加在原有内容后面 |
l |
列出非打印字符 |
p |
打印匹配行(和-n选项一块儿合用) |
= |
显示文件行号 |
{} |
定位执行的命令组,“;”隔开 |
n |
读入下一输入行,并从下一条命令而不是第一条命令开始处理 |
q |
结束或退出 sed |
r filename |
从另外一个文件中读文本,相似输入重定向 < |
! |
对所选行意外的全部行应用命令 |
s |
用一个字符串替换另外一个 |
g |
在行内进行全局替换 |
p |
打印行 |
w filename |
写文本到一个文件,相似输出重定向 > |
x |
交换暂存缓冲区与模式空间的内容 |
y |
传送字符,替换单个字符(不能对正则表达式使用 y 命令) |
元字符 |
功 能 |
示 例 |
示例的匹配对象 |
^ |
行首定位符 |
/^love/ |
匹配全部以 love 开头的行 |
$ |
行尾定位符 |
/love$/ |
匹配全部以 love 结尾的行 |
. |
匹配除换行外的单 |
/l..e/ |
匹配包含字符 l、后跟两个任意 |
* |
匹配零个或多个前 |
/*love/ |
匹配在零个或多个空格紧跟着 |
[] |
匹配指定字符组内 |
/[Ll]ove/ |
匹配包含 love 和 Love 的行 |
[^] |
匹配不在指定字符 |
/[^A-KM-Z]ove/ |
匹配包含 ove,但 ove 以前的那 |
\(..\) |
保存已匹配的字符 |
||
& |
保存查找串以便在 |
s/love/**&**/ |
符号&表明查找串。字符串 love |
\< |
词首定位符 |
/\<love/ |
匹配包含以 love 开头的单词的 |
\> |
词尾定位符 |
/love\>/ |
匹配包含以 love 结尾的单词的 |
x\{m\} |
连续 m 个 x |
/o\{5\}/ |
分别匹配出现连续 5 个字母 o、 |
x\{m,\} |
至少 m 个 x |
/o\{5,\}/ |
|
x\{m,n\} |
至少 m 个 x,但不 |
/o\{5,10\}/ |
[:digit:] |
全部数字,即[0-9] |
[:lower:] |
全部的小写字母 |
[:upper:] |
全部的大写字母 |
[:alpha:] |
全部的字母 |
[:alnum:] |
至关于0-9a-zA-Z |
[:space:] |
空白字符 |
[:punct:] |
全部标点符号 |
sed -n '1,4{=;p}' passwd
sed ‘/pattern/a new_str’file # 在匹配模式的下一行新,增str
sed ‘1a new_str‘ file # 在第1行后,新增str
# 过滤#注释行和空格行
sed –n ‘/^#/!{/^$/!p}’file
l /^#/!:打印除了#开头的行
l {/^$/!p}:打印除了空格行
# 删除#注释行和空行。有时-e的不一样顺序,会形成不一样结果。好比 -e ’1a’–e ‘2a’
sed –e ‘/^#/d’-e ‘/^$/d’ file
# 将hello所在行的END替换为tail
sed –i ‘/hello/s@END@tail@#’
l @:地址定界符,还能够是/,#等其余特殊字符
# 将目录下的.txt文件批量命名为.sh文件
find . –name ‘*.txt’ | sed –re ‘s#(.*).txt#mv & \1.sh#e’
l (.*).txt:查找的文件,对应&
l (.*):分组,对应\1,多个括号就依次对应\2,\3,…
l e:执行mv命令
# 删除文件中含有you这个单词的行。\必须加
sed ‘/\<you\>/d’file
linux sed命令详解(推荐) (http://www.jb51.net/article/111306.htm)
linux命令总结sed命令详解 (https://www.cnblogs.com/ginvip/p/6376049.html)
sed命令详解 (http://www.javashuo.com/article/p-knxuhypx-co.html)
grep适合单纯的查找或匹配文本。
--color=atuo或者—color:对匹配到的文本着色
-i:忽略大小写
-n:显示结果所在行号
-c:统计匹配到的行数。注意:是匹配到的总行数,不是匹配到的次数
-o:只显示符合条件的字符串,可是不整行显示。每一个符合条件的字符串单独显示一行
-v:接啥排除啥
-w:匹配整个单词,若是是字符创中包含这个单词,则不会匹配
-Ax:输出的时候包含结果所在行以后的指定行数,x是行数,A:after。若是有多个匹配结果。则每一个结果的后x行都会显示
-Bx:输出的时候包含结果所在行以前的指定行数,x是行数,B:before。
-Cx:输出的时候包含结果所在行以前和行以后的指定行数,x是行数,C:context
-e:实现多个选项的匹配,逻辑or关系
-q:静默模式,不输出任何信息。于“echo $?”合用,查看是否匹配到,0表示匹配到,1表示没有匹配到
-P:使用兼容的perl的正则
-E:使用扩展正则表达式,同egrep
# -e的使用
grep –e’one’ –e’two’ file # 能够同时匹配one和two
sed -nr 's#[:/0-9]+# #gp' passwd.txt #对passwd.txt文件进行处理,将 FS 变为空格
sed -nr 's#[:/0-9]+# #gp' passwd.txt | sed -nr 's# #\n#gp' | sort | uniq -c | sort –nr
l sed -nr 's#[:/0-9]+# #gp' passwd.txt #对passwd.txt文件进行处理,将 FS 变为空格
awk 'BEGIN{RS="[:/0-9]+"}{print $0}' passwd.txt | head -n -1 | sort | uniq -c | sort -nr # head -n -1 是由于最后一行是空行,须要排除
# awk使用{m,n},须要加--posix
awk --posix ‘$1~/o{1,2}/{print NR,$1}’passwd
sed -nr 's#^$##gp' file | wc -l
grep "^$" file |wc -l
awk '/^$/{a=a+1} END{print a}' file
awk -F: '{$3>5?a++:b++} END{print a}' /etc/passwd
awk -F: '$3>5{a++;print NR,$0} END{print a}' /etc/passwd
find $(echo $PATH | tr ":" "\n") -type f -name "???" 1> command 2>/dev/null;wc -l command
http://post.cbl.org/index.html
awk -F "/" '{a[$3]++} END{for(i in a){print i,a[i]}}' test
111 222 333 444 222 222 111 111 11 11
22 33 44 55 33 33 55 22
77 88 77 77 88 99 33 33
awk '{for(i=1;i<=NF;i++)a[$i,NR]++} \
{for (j in a) {split(j,m,SUBSEP);if(m[2]==NR)printf m[1]" "} printf "\n"}' test
l a[$i,NR]:二维数组
l for (j in a):遍历,j是二维数组
l split(j,m,SUBSEP):切割二维数组,SUBSEP是切割二维数组的分隔符
l printf m[1]:若是使用print,则每一个m[1],都会自动换行。printf不会,print须要自定义格式
lprintf "\n":换行。awk是一行一行处理的,一行处理完,换行,美化输出