awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
example.txt
name english Totalscore
jason 90 100
json 80 101
Mirro 78 102
cat example.txt | awk '{print $1,$3}'
执行结果:
cat /etc/passwd |awk -F ':' '{print $1}'
#显示分隔后的第一列和第三列,以tab键分隔
cat /etc/passwd |awk -F ':' '{print $1"\t"$3}'
#搜索example.txt有jason关键字的所有行
awk '/jason/' example.txt
#搜索example.txt有jason关键字的所有行,并显示第三列
awk '/jason/{print $3}' example.txt
#搜索支持正则,例如找jason开头的:
awk -F: '/^jason/' example.txt
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在第一行添加列名name,shell,在最后一行添加"end"。
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "end"}'
awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' example.txt
上面awk命令是先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,随后开始执行模式所对应的动作action。再读入第二条记录,直到所有的记录读完,最后执行END操作。
awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
上面的命令统计example.txt 文件名,每行的行号,每行的列数,对应的完整行内容,利用printf替代print,可以让代码更加简洁,易读,如下:
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' example.txt
awk中同时提供了print和printf两种打印输出的函数,其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。
awk还可以自定义变量
awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。这里没有初始化count,虽然默认,也可以初始化count:
awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
#统计某个文件夹下的文件占用的字节数
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
#统计某个文件夹下的文件(不含子目录)占用的字节数,以M为单位显示
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'
#awk中使用for循环遍历数组
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
awk的用法极多,更多请参考 http://www.gnu.org/software/gawk/manual/gawk.html
sed是一种流编辑器,在文本处理中非常适用的工具,能够配合正则表达式使用。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。
sed命令格式
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
常用选项:删除某行:
sed '1d' example.txt #删除第一行
sed '$d' example.txt #删除最后一行
sed '1,2d' example.txt #删除第一行到第二行
sed '2,$d' example.txt #删除第二行到最后一行
显示某行:
sed -n '1p' example.txt #显示第一行
sed -n '$p' example.txt #显示最后一行
sed -n '1,2p' example.txt #显示第一行到第二行
sed -n '2,$p' example.txt #显示第二行到最后一行
模式进行查询:
sed -n '/ruby/p' example.txt #查询包括关键字ruby所在所有行
sed -n '/\$/p' example.txt #查询包括关键字$所在所有行,使用反斜线\屏蔽特殊含义
替换一行中的某部分:
#格式:sed 's/要替换的字符串/新的字符串/' (要替换的字符串可以用正则表达式)
sed -n '/jason/p' example.txt | sed 's/jason/bird/' #替换jason为bird
sed -n '/jason/p' example.txt | sed 's/jason//g' #删除jason,h后面添加g表示全部替换
sed替换标记:
命令 | 说明 |
---|---|
g | 表示行内全面替换 |
p | 表示打印行 |
w | 表示把行写入一个文件 |
x | 表示互换模板块中的文本和缓冲区中的文本 |
y | 表示把一个字符翻译为另外的字符(但是不用于正则表达式) |
\1 | 子串匹配标记 |
& | 已匹配字符串标记 |
sed '/^$/d' test.txt #删除空白行
sed '/^aa/'d test.txt # 删除文件中所有以aa开头的行,sed -i '/匹配字符串/d' file
#从第N处匹配开始替换时,可以使用 /Ng
sed 's/book/books/g' file #使用后缀 /g 标记会替换每一行中的所有匹配
echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'
命令中 digit 7,被替换成了 7。样式匹配到的子串是 7,\(..\) 用于匹配子串,对于匹配到的第一个子串就标记为 \1,依此类推匹配到的第二个结果就是 \2
组合多个表达式
sed '表达式' | sed '表达式' <==> sed '表达式; 表达式'
sed表达式可以使用单引号来引用,但是如果表达式内部包含变量字符串,就需要使用双引号。
test=hello
echo hello WORLD | sed "s/$test/HELLO"
HELLO WORLD
这两个命令用法都很多,没有一一列举,只是列举了下自己用得比较多的,有兴趣的可以自己去再收集下。参考文档:
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html
http://man.linuxde.net/sed
http://www.cnblogs.com/maxincai/p/5146338.html