awk&sed入门(可编程过滤器awk与流编辑器sed)

参考:李中国老师的课件

可编程过滤器awk

历史

  略

awk: 为什么叫做可编程过滤器 ?

  • awk 可以读标准输入并写标准输出 , 因此符合经典过滤
    器模式的程序定义
  • 但是 awk 与 grep,tr,wc,sort,uniq 等功能单一的过滤器程序的最大不同之处 , 是它的文本过滤功能需要通过用户自己编程去实现 , 因此更加强大、丰富、灵活

准备数据:emp.data,分隔符为空格

Beth	4.00	0
Dan	3.75	0
Kathy	4.00	10
Mark	5.00	20
Mary	5.50	22
Susie	4.25	18

awk 可编程过滤器的五种使用方式

方式一
cat emp.data | awk '$3 > 0 { print $1, $2 * $3 } '
方式二
awk '$3 > 0 { print $1, $2 * $3 } ' emp.data
方式三
awk -f programfile emp.data
方式四
cat emp.data | awk -f programfile
方式五
chmod +x programfile
cat emp.data | ./programfile

./programfile emp.data


awk源文件programfile: 注意第一行#! /usr/bin/awk -f

#! /usr/bin/awk -f
$3 > 0 { print $1, $2 * $3 }
#$3 > 0 {print $1,$2*$3}
#$3 > 0 {print $1, $2*$3}
#$3 > 0 {print $1, $2* $3 }
#$3 > 0 {print $1"\t"$2*$3}

awk 程序的基本结构

awk '模式 + { 动作 }'

只有动作:默认模式为匹配所有行
awk ’ { print $1 } ’ emp.data

只有模式:默认动作为打印匹配的行
awk ’ $3 == 0 ’ emp.data

awk 程序的特殊模式:

BEGIN

  在读入文件之前执行。

命令行

[sy@sy-pc script]$ awk 'BEGIN {print "Name Rate Hours";print "" }{ print }' emp.data 
Name Rate Hours

Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18

程序文件
#注意:BEGIN 与 { 必须在同一行

[sy@sy-pc script]$ cat programfile.sh 
#! /usr/bin/awk -f
BEGIN {	#注意:这里的BEGIN 与 { 必须在同一行
	print "Name Rate Hours"
	print ""
}
{
	print
}
[sy@sy-pc script]$ ./programfile.sh emp.data 
Name Rate Hours

Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18

END

  在读完文件之后执行。
#注意:END与 { 必须在同一行

[sy@sy-pc script]$ cat programfile.sh 
#! /usr/bin/awk -f
$3>15{emp=emp+1}	#每个符号之间可以有空格  $3 > 15 { emp = emp + 1 }
END {	#注意:END与 { 必须在同一行
	print emp, "employess worked more than 15 hours"
}
[sy@sy-pc script]$ ./programfile.sh emp.data 
3 employess worked more than 15 hours

awk 程序的特殊变量: NR 与 NF

  • NR: 记录当前行号
  • NF: 当前行内字段数
  • $0: 当前整行的内容
  • F: 指定分隔符
[sy@sy-pc script]$ awk '{print NR, $0}' emp.data 
1 Beth 4.00 0
2 Dan 3.75 0
3 Kathy 4.00 10
4 Mark 5.00 20
5 Mary 5.50 22
6 Susie 4.25 18
[sy@sy-pc script]$ cat programfile.sh 
#! /usr/bin/awk -f
{print NR, $0}
$ ./programfile.sh emp.data

  计算某文件有多少个字符:
思考:程序中为什么要+1?

[sy@sy-pc script]$ cat programfile.sh 
#! /usr/bin/awk -f
{	nc=nc+=length($0) + 1
	nw=nw+NF
}
END {
	print NR, "lines,", nw, "words,", nc, "characters"
}
[sy@sy-pc script]$ ./programfile.sh emp.data 
6 lines, 18 words, 77 characters

  -F 指定分隔符的使用方式

[root@sy-pc ~]$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

[root@sy-pc ~]$ cat /etc/passwd | awk -F : 'BEGIN {print "name\tshell"} {print $1","$7} END {print "blue,/bin/nosh"}'
name	shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
......
blue,/bin/nosh

awk 控制结构

  与 C 语言一样 ,awk 支持 if 语句、 for 循环、 while 循环等控制语句 ( 具有相同的语法 ):

  将负数转成正数显示:

[sy@sy-pc script]$ cat programfile.sh 
#! /usr/bin/awk -f
{
	for (i = 1; i <= NF; i = i + 1){
		if ($i < 0) 
			$i = -$i
	}
	print
}

或者

[sy@sy-pc script]$ cat programfile.sh 
#! /usr/bin/awk -f
{	for (i = 1; i <= NF; i = i + 1) if ($i < 0) $i = -$i
	print
}

awk 数组

  将文件内容,按每一行倒叙显示:

[sy@sy-pc script]$ cat programfile.sh 
#! /usr/bin/awk -f
{ line[NR]=$0}
END { for (i=NR; i>0; i=i-1)
	print line[i]
}
[sy@sy-pc script]$ ./programfile.sh emp.data 
Susie 4.25 18
Mary 5.50 22
Mark 5.00 20
Kathy 4.00 10
Dan 3.75 0
Beth 4.00 0


流编辑器sed

简介

  • sed = stream editor
  • 流编辑器 sed
    • 它编辑的对象通常是 Unix 管道中的文本流 , 故名
    • 诞生于 1973 – 1974 年 , 发明人是贝尔实验室的 LeeE. McMahon ( 毕业于哈佛大学 )
    • 常常作为过滤器应用于管道之中 , 实现对文本的自动编辑处理 ; 与 awk 类似 , 其编辑功能同样是可编程的(programmable)
  • sed 是标准的过滤器模式的程序
    • … | sed ‘s/xxx/yyy/g’ | …

替换命令 s

  sed 最基本、最重要的命令 s :文本替换
注意:

  • 变更对象限制在特定的行,例如只想替换第2行内容,只需写为"2s"
  • 无g 匹配到一块后,停止这一行后面字符串的匹配;
  • 有g 匹配所有的字符串,即贪婪匹配;
  • 正则表达式及替换文本的分割符 / 可以换成其它符号;
  • 在被替换字符串中 , 可以用符号 & 表示前面正则表达式匹配的内容;这一特性在进行文本替换时非常有用;
  • 在正则表达式及被替换字符换中,可用 \number 表示第几个匹配的字符串;匹配字符串如需参加编号 , 则用 \( 和 \) 标志:
  • 无-r参数,大括号、小括号 需要加转义字符
  • 有-r 参数,可以省略 正则表达式中的转义字符;

例1:

[sy@sy-pc script]$ echo "123abc" | sed 's/[0-9][0-9]*/& &/'
123 123abc

例2:

[sy@sy-pc script]$ cat input.txt 
2014-03-03,37.92,38.13,37.49,37.78,29717500,37.78
2014-03-04,37.93,38.14,37.50,37.77,29717500,37.78
2014-04-05,37.94,38.15,37.51,37.77,29717511,37.79
2014-04-06,37.95,38.16,37.52,37.76,29717511,37.79
[sy@sy-pc script]$ cat input.txt | sed 's/,/\t/g' > output.txt
[sy@sy-pc script]$ cat output.txt 
2014-03-03	37.92	38.13	37.49	37.78	29717500	37.78
2014-03-04	37.93	38.14	37.50	37.77	29717500	37.78
2014-04-05	37.94	38.15	37.51	37.77	29717511	37.79
2014-04-06	37.95	38.16	37.52	37.76	29717511	37.79

只处理第2行 2s

[sy@sy-pc script]$ cat input.txt | sed '2s/,/\t/g' > output.txt  
[sy@sy-pc script]$ cat output.txt 
2014-03-03,37.92,38.13,37.49,37.78,29717500,37.78
2014-03-04	37.93	38.14	37.50	37.77	29717500	37.78
2014-04-05,37.94,38.15,37.51,37.77,29717511,37.79
2014-04-06,37.95,38.16,37.52,37.76,29717511,37.79

例3:

[sy@sy-pc script]$ cat telephone.txt 
4000001476
4000000049
4000000041
4000002754
[sy@sy-pc script]$ cat telephone.txt | sed 's/[0-9]\{3\}/(&)/'
[sy@sy-pc script]$ cat telephone.txt | sed -r 's/[0-9]{3}/(&)/'
(400)0001476
(400)0000049
(400)0000041
(400)0002754

例4:

[sy@sy-pc script]$ cat telephone.txt | sed 's/\([0-9]\{3\}\)\([0-9]\{3\}\)/\1-\2-/'
[sy@sy-pc script]$ cat telephone.txt | sed -r 's/([0-9]{3})([0-9]{3})/\1-\2-/'
400-000-1476
400-000-0049
400-000-0041
400-000-2754

参数 -i

永久关闭CentOS 7的SELInux

sed -i "s#SELINUX=enforcing#SELINUX=disabled#g" /etc/selinux/config
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值