sed
- sed基础知识
sed(stream editor):
一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,处理完成之后把缓冲区的内容送往屏幕,接着处理下一行,这样不断重复,直到文件末尾。(不改变文件内容,只是显示出所做的改变) - Sed 对字符的处理
sed [参数] ‘命令’ file
p ##显示
d ##删除
a ##添加
c ##替换
i ##插入
s ##替换
w ##整合
-
p 显示,将某个选择的数据打印显示。通常 p 会与参数 sed -n 一起执行
[root@fuwu test]# cat -n /etc/fstab 1 2 # 3 # /etc/fstab 4 # Created by anaconda on Wed May 7 01:22:57 2014 5 # 6 # Accessible filesystems, by reference, are maintained under '/dev/disk' 7 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info 8 # 9 UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1 [root@fuwu test]# sed -n '/\:/p' /etc/fstab ##显示含有:的行(:需要转译) # Created by anaconda on Wed May 7 01:22:57 2014 [root@fuwu test]# sed -n '/^#/p' /etc/fstab ##显示以#开头的行 # # /etc/fstab # Created by anaconda on Wed May 7 01:22:57 2014 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # [root@fuwu test]# sed -n '/^#/!p' /etc/fstab ##显示不以#开头的行 UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1 [root@fuwu test]# sed -n '2,6p' /etc/fstab ##显示2-6行 # # /etc/fstab # Created by anaconda on Wed May 7 01:22:57 2014 # # Accessible filesystems, by reference, are maintained under '/dev/disk' [root@fuwu test]# sed -n '2,6!p' /etc/fstab ##显示除了第2行和第6行的行 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1
-
d 删除,显示模式空间删除指定行后的内容,不会对原文件数据删除
[root@fuwu test]# sed '/^UUID/d' /etc/fstab ##删除以UUID开头的行
#
# /etc/fstab
# Created by anaconda on Wed May 7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
[root@fuwu test]# sed '/^$/d' /etc/fstab ##删除空行
#
# /etc/fstab
# Created by anaconda on Wed May 7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1
[root@fuwu test]# sed '1,4d' /etc/fstab ##删除1-4行
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1
- a 添加,a 的后面可以接字符串,该字符串会在当前指定行的下一行出现
[root@fuwu test]# cat hello.sh
hello
[root@fuwu test]# sed '/hello/aworld' hello.sh
hello
world
[root@fuwu test]# sed 's/hello/hello world/g' hello.sh
hello world
[root@fuwu test]# sed 's/hello/hello\nworld/g' hello.sh
hello
world
- c 更改, c 的后面可以接字符串,该字符串可以取代 n1,n2 之间的行
[root@fuwu test]# sed '/hello/chello world' hello.sh
hello world
- i 插入, i 的后面可以接字符串,该字符串会在当前指定行的上一行出现
[root@fuwu test]# sed '/hello/iworld\nwestos' hello.sh
world
westos
hello
- s:替换,格式sed ‘s/A/B/g’ passwd ##将passwd文件中的所有的A替换成B
[root@squid mnt]# cat 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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@squid mnt]# sed 's/nologin/bash/g' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/bash
daemon:x:2:2:daemon:/sbin:/sbin/bash
adm:x:3:4:adm:/var/adm:/sbin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/bash
operator:x:11:0:operator:/root:/sbin/bash
1. sed 's/nologin/bash/g' passwd ##将passwd文件中的所有的nologin替换成bash
2. sed '1,5s/nologin/bash/g' passwd ##将passwd文件中1到5行的nologin替换成bash
3. sed -e '2s/nologin/bash/g;4s/nologin/bash/g' passwd ##将passwd文件中2和4行的nologin替换成bash
在sed替换中@相当于/
1. sed ‘s@\/@ @g’ passwd ##将passwd中的/替换成空格
2. sed ‘G’ passwd ## 将passwd文件每一行后加入一个空行
3. sed ‘$!G’ passwd ## 将passwd文件每一行后加入一个空行,除了最后一行
- w 整合,
[root@squid mnt]# cat fstab
#
# /etc/fstab
# Created by anaconda on Wed May 7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1
[root@squid mnt]# touch testfile
[root@squid mnt]# sed '/^#/w /mnt/testfile' fstab
[root@squid mnt]# cat testfile
#
# /etc/fstab
# Created by anaconda on Wed May 7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
例:
1. sed '/^#/w /etc/testfile' fstab ###将fstab中的以#开头的行整合到/etc/testfile中
2. sed '5r /etc/hello' /mnt/fstab ###将/etc/hello文件内容整合到/mnt/fstab的第五行
3. sed 'r /etc/hello' /mnt/fstab ##将/etc/hello文件内容整合到/mnt/fstab的每一行
注意:添加或者整合到文件的最后一行时用追加的形式:echo ‘’
添加或者整合时添加多行要用 \n来换行
-
练习:更改httpd服务的端口
[root@fuwu test]# cat dk.sh #!/bin/bash yum install -y httpd &> /dev/null sed -i "/^Listen/cListen $1" /etc/httpd/conf/httpd.conf echo -e "Port has changed!" echo "Now ,Port is $1!" systemctl restart httpd [root@fuwu test]# sh dk.sh 8080 Port has changed! Now ,Port is 8080!
awk:报告生成器
- awk处理机制:awk 会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行做一些总结性质的工作, 根据模式一次从文件中抽取一行文本,对这行文本进行切片(默认使用空白字符作为分隔符)。在命令格式上分别体现如下:
- BEGIN{}:读入第一行文本之前执行,一般用来初始化操作。
- {}:逐行处理,逐行读入文本执行相应的处理,是最常见的编辑指令块。
- END{}:处理完最后一行文本之后执行,一般用来输出处理结果。
[root@fuwu test]# cat ll.sh
this is a apple
$1 $2 $3 $4
[root@fuwu test]# awk '{print $0}' ll.sh ##$0表示输出一整行
this is a apple
[root@fuwu test]# awk '{print $1}' ll.sh
this
[root@fuwu test]# awk '{print $1,$2}' ll.sh ##显示两个字段
this is
- 指定分隔符
[root@fuwu test]# awk -F ":" '{print $1,$3}' /etc/passwd ###以:为分隔符,打印文件/etc/passwd的第一列和第三列
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
....
[root@fuwu test]# awk '{print FILENAME,NR}' /etc/passwd
/etc/passwd 1
/etc/passwd 2
/etc/passwd 3
/etc/passwd 4
/etc/passwd 5
...
- awk的常用变量
[root@fuwu test]# awk '{print FILENAME,NR}' /etc/passwd ####打印文件/etc/passwd的文件命令和行号
/etc/passwd 1
/etc/passwd 2
/etc/passwd 3
/etc/passwd 4
/etc/passwd 5
...
[root@fuwu test]# awk -F: '{print NR,NF}' /etc/passwd ###打印文件/etc/passwd的行号和以":"为分隔符的字段个数
1 7
2 7
3 7
...
[root@fuwu test]# awk -F: '$3 >= 0 && $3 < 2 {print $1,$3}' /etc/passwd ###输出/etc/passwd下uid小于等于2的用户名和uid
root 0
bin 1
awk两个特殊模式(BEGIN 和 END)
BEGIN{}: 读入第一行文本之前执行的语句,一般用来初始化操作
{}: 逐行处理
END{}: 处理完最后以行文本后执行,一般用来处理输出结果
[root@fuwu test]# awk 'BEGIN { a=14;print a+134 }'
148
[root@fuwu test]# awk -F: 'BEGIN{print "REDHAT"} {print NR;print } END {print "WESTOS"}' /etc/passwd ####文件开头加REDHAT,末尾加WESTOS,打印行号和内容
REDHAT
1
root:x:0:0:root:/root:/bin/bash
2
bin:x:1:1:bin:/bin:/sbin/nologin
3
daemon:x:2:2:daemon:/sbin:/sbin/nologin
4
adm:x:3:4:adm:/var/adm:/sbin/nologin
5
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
....
统计文本总字段个数
[root@fuwu test]# cat ll.sh
this is a apple
fsg hh
fds
dfgg
[root@fuwu test]# awk 'BEGIN{i=0}{i+=NF}END{print i}' ll.sh
8
awk示例:
1. 能登陆到系统的用户名称
[root@squid mnt]# awk -F : '/bash$/{print $1}' passwd
root
student
2. 能登陆到系统的用户个数
[root@squid mnt]# awk -F : BEGIN{i=0}'/bash$/{i++}END{print i}' passwd
2
3. 能登陆到系统但是家目录不在home下的系统用户名称
[root@squid mnt]# awk -F : '$6!~/\<home$/&&/bash$/{print $1}' passwd
root
student
注意:“\< 此符号为不要有扩展的意思”
4. 能登陆到系统但是家目录不在home下的系统用户个数
[root@squid mnt]# awk -F : BEGIN{i=0}'$6!~/\<home$/&&/bash$/{i++}END{print i}' passwd
2
5. 打印passwd文件中以a或b或c或d开头的行
[root@squid mnt]# awk '/^[a-d]/{print}' passwd
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
dbus:x:81:81:System message bus:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
colord:x:997:995:User for colord:/var/lib/colord:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
6. 打印除了以a-k开头的行
[root@squid mnt]# awk '!/^[a-t]/{print}' passwd
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
unbound:x:995:993:Unbound DNS resolver:/etc/unbound:/sbin/nologin
或者是 : awk '/^[^a-d]/{print}' passwd
7. 打印以a开头或者以bash结尾的行
[root@squid mnt]# awk '/^a|bash$/{print}' passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
student:x:1000:1000:Student User:/home/student:/bin/bash
abrt:x:173:173::/etc/abrt:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
8. 打印不是以a开头但是可以以bash结尾的行
[root@squid mnt]# awk '/!~^a|bash$/{print}' passwd
root:x:0:0:root:/root:/bin/bash
student:x:1000:1000:Student User:/home/student:/bin/bash
9. 打印不以a开头不以bash结尾的行
[root@squid mnt]# awk '!/^a|bash$/' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
10. 打印以:为分隔符的第六列以bin结尾的行
[root@squid mnt]# awk -F : '$6~/\<bin$/{print}' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
11. 打印以:为分隔符的第六列不以bin结尾的行
[root@squid mnt]# awk -F : '$6!~/\<bin$/{print}' passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
awk高级应用(条件判断、循环)
- if单分支语句
[root@fuwu test]# awk -F: 'BEGIN{i=0}{if($7~/bash$/){i++}}END{print i}' /etc/passwd ###统计登录shell为bash的用户
4
[root@fuwu test]# awk -F: 'BEGIN{i=0}{if($3<500){i++}}END{print i}' /etc/passwd ###统计/etc/passwd下uid小于500的用户个数
31
[root@fuwu test]# awk 'BEGIN{do {++i;print i} while (i<3)}'
1
2
3
- if双分支
[root@server19 mnt]# awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}' /etc/passwd ###统计uid小于等于500和大于500的用户个数
31 9
- for循环
[root@fuwu test]# awk 'BEGIN{for(i=1;i<=5;i++){print i}}' ###生成1-5序列
1
2
3
4
5
- while循环
[root@fuwu test]# awk 'i=1 {} BEGIN{while (i<3){i++;print i}}'
1
2
3
[root@fuwu test]# awk 'BEGIN{do {++i;print i} while (i<3)}'
1
2
3