Linux三剑客(grep、sed、awk)

一、grep

常见参数:

    -i: 忽略大小写。
    -v: 反向匹配,输出不包含模式的行。    
    -n: 在每一行前面加上行号。
    -r or -R: 递归方式在所有文件中搜索。
    -E: 使用扩展正则表达式。
    -P: 使用 Perl 兼容的正则表达式。
    -o: 仅输出匹配模式的部分。
    -l: 仅输出包含匹配行的文件名。
    -e: 指定多个搜索模式。
    -A数字  #列出符合条件的行,并连续列出后续n行(如果小写,列出前后n行)。
    -B数字  #列出符合条件的行,并连续列出前面n行(如果小写,列出前后n行)。
    -C数字  #列出符合条件的行,并连续列出前后n行(如果小写,列出输出匹配模式的行数。)

例:
grep -i 'pattern' file.txt

二、sed

sed    [选项] ‘[动作]’ 文件名

常见参数:
    -n        一般sed命令会把所有数据都输出到屏幕,如果加入此选项,则只会把经过sed命令处理的行输出到屏幕。
    -e       允许对输入数据应用多条sed命令编辑。
    -f 脚本文件名          从sed脚本中读入sed操作。和awk命令的-f非常相似。
    -r        在sed中支持扩展正则表达式。
    -i         用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出动作。
输出动作:
    a        追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用\代表数据未完结。
    c        行替换,用c后面的字符串替换原数据行。替换多行时,除最后一行外,每行末尾需要用\代表数据未完结。
    i        插入,在当前行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用\代表数据为完结。
    d        删除,删除指定的行。
    p        打印,输出指定的行。
    s        字符串替换,用一个字符串替换另外一个字符串。格式为“行范围s/旧字串/新字串/g”(和vim中替换格式类似)

例:
sed -i 's/old/new/g' file.txt

三、awk

awk使用格式:awk '条件1{动作1} 条件2{动作2}' 文件名

条件(Pattern):
    一般使用关系表达式作为条件。这些关系表达式非常多。
    例如:x>10        判断变量x是否大于10
        x == y        判断变量x是否等于y
        A !~ B        判断字符串A是否不包含能匹配B表达式的字符串
动作(Action):
    格式化输出 
    流程控制语句

1.基本使用

awk -F ":" '{ print $1 "\t" $3}' /etc/passwd
    #以:为分隔符,输出/etc/passwd的第二列和第三列。

2.awk条件

(1)保留字

BEGIN    

        在awk程序一开始,未读取任何数据之前执行BEGIN后的动作只在程序开始执行一次。


END    

        在awk程序处理完所有数据,即将结束执行。END后的动作只在程序结束时执行一次。

例:
[root@localhost ~]# awk 'BEGIN {printf "This is a cj \n"} {printf $2 "\t" $4 "\n"}' cj.txt 
This is a cj 
Name        Mark 
zhaosan     87.12 
lisi        90.123
wangwu     89.1233322

[root@localhost ~]# awk 'END {printf "The END \n"} {printf $2 "\t" $4 "\n"}' cj.txt 
Name        Mark 
zhaosan     87.12 
lisi        90.123
wangwu     89.1233322 
The END 

(2)关系运算符

>    大于
<    小于
>=    大于等于
<=    小于等于
==    等于。用于判断两个值是否相等,如果是变量赋值请使用“=”号 
!=    不等于
~    判断字符串A中是否包含能匹配B表达式的字符串
!~    判断字符串A中 是否不包含能匹配B表达式的字符串

 

例如:
[root@localhost ~]# cat cj.txt | grep -v Name | awk '$4 >= 89 {printf $2 "\n"}' 
lisi
wangwu
#加入了条件之后,只有条件成立动作才会执行,如果条件不满足,则动作不运行。虽然awk是列提取命令,但是也要按行来读入的。

[root@localhost ~]# awk '$2~ /lisi/ {printf $4 "\n"}' cj.txt 
90.123
#先匹配第2列为lisi的行,再输出此行的第4列。
#在awk中使用//包含的字符串,awk命令才会查找。也就是说字符串必须使用//包含, awk命令才能正确识别。

3.内置变量

$0    代表目前awk所读入的整行数据。我们已知awk是一行一行读入数据的,$0就代表当前读入行的整行数据。


$n    代表目前读入行的第n个字段。


NF    当前行拥有的字段(列)总数。
NR    当前awk所处理的行,是总数据的第几行。
FS    用户定义分隔符。awk的默认分隔符是空格。如果想要使用其他分隔符需要FS 变量定义。
  

 例:
cat /etc/passwd | grep "/bin/bash" | awk '{FS=":"} {printf $1 "\t" $3 "\n"}'
root:x:0:0:root:/root:/bin/bash 
#这里“:”生效了。但是并没有把第一列和第三列截取出来,继续用BEGIN命令试试
        
cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN{FS=":"} {printf $1 "\t" $3 "\n"}'
root    0
#成功截取第一和第三字段的内容
        
cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN {FS=":"} {printf $1 "\t" $3"\t" NR "\t"NF"\n"}'
root        0    1    7
#分隔符是":"输出第一字段和第三字段 输出行号(NR)字段数(NF)如果只想查看sshd这个伪用户的相关信息需要: 
        
cat /etc/passwd | awk 'BEGIN {FS=":"} $1=="sshd" {printf $1 "\t" $3 "\t" NR "\t" NF "\n"}'
sshd    74    32    7
#可以看到sshd伪用户的UID是74,是/etc/passwd文件的第32行,共有7个字段

4.流程控制

[root@localhost ~]# cat /root/cj.txt 
ID	Name		gender	 Mark
1 	zhaosan	 M 		87.12
2 	lisi		 M 		90.123
3 	wangwu 	 M 		89.1233322
#统计本次成绩的总分 

[root@localhost ~]# awk 'NR==2{cj1=$4}
> NR==3{cj2=$4}
> NR==4{cj3=$4;totle=cj1+cj2+cj3;print "totle cj is" totle}' cj.txt 	 
totle cj is266.366 	 	 	 	 	 	 	 	                                                             #实现流程控制,假设如果成绩大于90,就是goodboy:

[root@localhost ~]# awk '{if (NR>=2) {if ($4>=90) print $2 " is a good boy \n"}}' cj.txt
lisi is a good boy 

5.调用脚本

[root@localhost ~]# cat pass.awk 
BEGIN	{FS=":"}
{print$1"\t"$3}

[root@localhost ~]# awk -f pass.awk /etc/passwd	#用-f选项来调用这个脚本。
root		0
bin		1
daemon   2
#此脚本可以用于/etc/passwd、/etc/shadow、/etc/group等以:为分隔符文件的查看。

你可能感兴趣的:(Linux系统基础,linux,运维,服务器)