awk和sed命令详解

1、awk命令

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,把文件逐行的读入以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk命令形式:
awk [-F|-f|-v]  'commands' input-file(s)
 [-F|-f|-v] -F指定分隔符,-f调用脚本,-v定义变量 var=value
'commands  '      可以是引用代码块 'BEGIN{}  {command1; command2} END{}'
BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,命令代码块可包含一条或多条命令
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
如果只需要文本中某列信息,或某几列信息
example.txt 
name english Totalscore
jason  90     100
json   80     101
Mirro  78     102
cat example.txt | awk '{print $1,$3}'
执行结果:
awk和sed命令详解_第1张图片

awk命令执行时,会先读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键",上面没有使用"-F"指定分隔符,下面命令指定分隔符为":",显示/etc/passwd的第一列,即账户
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

2、sed命令

sed是一种流编辑器,在文本处理中非常适用的工具,能够配合正则表达式使用。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。

sed命令格式

sed [options] 'command' file(s) 
sed [options] -f scriptfile file(s)
常用选项:
        -n∶sed 的用法中,所有来自 STDIN的资料都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。 

常用命令:
        a   ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
        c   ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
        d   ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
         i   ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
         p  ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~
         s  ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

删除某行:

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

你可能感兴趣的:(常用命令)