文件处理三剑客之sed,awk

基础正则表达式

  • \ 转义字符,用于取消特殊字符的含义
  • ^ 匹配以字符串开头
[root@localhost ~]# grep "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
  • $ 匹配以字符串结尾
[root@localhost ~]# grep "bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
hebin:x:1000:1000:hebin:/home/hebin:/bin/bash
wangwu:x:1003:1003::/home/wangwu:/bin/bash
zhangsan:x:1004:1004::/home/zhangsan:/bin/bash
lisi:x:1007:1007::/home/lisi:/bin/bash

  • . 匹配除换行外任一字符
[root@localhost ~]# grep "ba.h" /etc/passwd
root:x:0:0:root:/root:/bin/bash
hebin:x:1000:1000:hebin:/home/hebin:/bin/bash
wangwu:x:1003:1003::/home/wangwu:/bin/bash
zhangsan:x:1004:1004::/home/zhangsan:/bin/bash
lisi:x:1007:1007::/home/lisi:/bin/bash

  • * 匹配前面的子表达式0次或多次
[root@localhost ~]# grep "ba*sh" /etc/passwd
root:x:0:0:root:/root:/bin/bash
hebin:x:1000:1000:hebin:/home/hebin:/bin/bash
wangwu:x:1003:1003::/home/wangwu:/bin/bash
zhangsan:x:1004:1004::/home/zhangsan:/bin/bash
lisi:x:1007:1007::/home/lisi:/bin/bash

  • [ ] 匹配包含括号里面的字符串,或的关系
[root@localhost ~]# grep "b[acd]sh"  p.txt 
root:x:0:0:root:/root:/bin/bash
bcsh
bdsh
  • [ ^ ] 匹配除括号里的其他字符串
[root@localhost ~]# grep "b[^ac]sh"  p.txt 
bdsh

  • {n} 匹配前面的子表达式n次,1是一位数,2是两位数
[root@localhost ~]# grep "[0-9]\{2\}"  p.txt 
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# grep "[0-9]\{1\}"  p.txt 
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
  • {n,m} 匹配前面子表达式n到m次
[root@localhost ~]# grep "[0-9]\{1,2\}"  p.txt  //一位数两位数都匹配
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

扩展正则表达式

  • + 匹配前面的子表达式1次以上
[root@localhost ~]# egrep "lo+d"  p.txt 
loood
lodlodlood
lood

  • ? 匹配前面的子表达式0次或1次
[root@localhost ~]# egrep "lo?d"  p.txt 
lodlodlood
ld
  • | 以或方式匹配字符串
[root@localhost ~]# egrep "lo.d|ba.h"  p.txt 
root:x:0:0:root:/root:/bin/bash
lodlodlood
lood

sed工具

sed在处理数据时默认不修改源文件,依赖于正则表达式

  • sed ‘’ p.txt 将内容全部打印到屏幕
  • sed ‘p’ p.txt 打印两边内容
  • sed -n ‘3p’ p.txt 打印第三行
  • sed -n ‘1,3p’ p.txt 打印一到三行
  • sed -n ‘$p’ p.txt 打印最后一行
  • sed -n ‘1~3p’ p.txt 从第一行开始,每隔3行打印一次
[root@localhost ~]# cat -n p.txt |sed -n '1~3p' 
     1	root:x:0:0:root:/root:/bin/bash
     4	adm:x:3:4:adm:/var/adm:/sbin/nologin
     7	shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    10	operator:x:11:0:operator:/root:/sbin/nologin
    13	bdsh
    16	lood

  • sed -n ‘2p;3p’ /p.txt 打印2行和3行
  • sed -n ‘/root/p’ p.txt 打印有root的行
  • sed -n ‘/^root/p’ p.txt 打印以root开头的行
  • sed -n ‘/root$/p’ p.txt 打印以root结尾的行
  • sed -nr ‘/^root|bash$/p’ p.txt 打印以root开头或bash结尾的行
  • sed -ne ‘/^root/p’ -e ‘/bash$/p’ p.txt 多个条件时可以使用
  • sed -n ‘/^$/p’ p.txt 打印空行
  • sed -n ‘/ /p’ p.txt 打印空格的行
  • sed -n ‘s#/bin/bash#xxx#p’ p.txt 将/bin/bash替换成xxx
  • sed ‘1d’ 删除第一行
  • sed '$d’删除最后一行
  • sed ‘/^root/d’ 删除以root开头的行
  • sed -n ‘/root/Ip’ 忽略大小写打印root的行
  • sed -n ‘s/^bin/#&/p’ 在bin开头添加#
  • sed ‘1a hello world’ p.txt 在第一行下面插入hello world
  • sed ‘1i hello world’ p.txt 在第一行上面插入hello world
  • sed ‘r /etc/hosts’ p.txt 将文件读进p.txt中
  • sed ’ w /opt/bak’ p.txt 将p.txt读进/opt/bak中
  • sed -n ‘/root/cxxx’ p.txt 将root整行替换成xxx
  • sed ‘=’ p.txt 显示行号
  • sed ‘5q’ p.txt 打印到第五行结束退出
  • sed -i ’ ’ p.txt 修改p.txt内容
  • sed -i.bak 先建一个备份文件再修改

小试题

删除文件每行第一个字符

sed  's/^.//' pass.txt

把文件每一行开头第一个空格删除

sed  's/^ //' pass.txt

把文件每一行里的所有空格都删除

sed  's/ //g' pass.txt 

删除文件每行里的所有数字

sed  's/[0-9]//g' pass.txt

删除test.txt中所有特殊字符

sed  's/[^a-Z0-9]//g' pass.txt

用sed匹配出文档中的有效手机号

sed -n '/1[3578]\{1\}[0-9]\{9\}/p' pass.txt

用sed修改网卡配置文件,ip地址为一个静态ip,并配置ip、网关、子网掩码、dns

sed -e 's/dhcp/static/' -e '$a IPADDR=192.168.30.10\nNETMASK=255.255.255.0\nGATEWAY=192.168.30.2\nDNS1=114.114.114.114' /etc/sysconfig/network-scripts/ifcfg-ens33

用sed修改ssh服务配置文件,去掉所有以#开头的行和空行,改变端口为2222,不允许root用户登录连接,修改UseDNS为no

sed  -e 's/#Port 22/Port 2222/' -e 's/#PermitRootlogin yes/PermitRootlogin no/' -e 's/#UseDNS yes/UseDNS no/' -e '/^#/d' -e '/^$/d' /etc/ssh/sshd_config

awk工具

awk是一个功能强大的编辑工具,用于对文本和数据进行处理
awk逐行读取文本,默认以空格为分隔符进行分隔

  • awk ‘{ print}’ p.txt 打印所有行
[root@localhost ~]# awk '{ print}' p.txt 
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
bacsh
bcsh

  • awk ‘{ print $1}’ p.txt 打印第一列
[root@localhost ~]# awk '{ print $1}' p.txt
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
bacsh
bcsh
bdsh
loood
lodlodlood
lood
ld

  • awk -F: ‘{ print $1}’ p.txt 修改分隔符为:打印第一列
[root@localhost ~]# awk -F: '{ print $1}' p.txt
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
bacsh
bcsh
bdsh
loood
lodlodlood
lood
ld

  • awk -F: ‘{ print “用户名”$1"的uid"$3}’ /etc/passwd 输入常量时需要用" ",变量就直接使用
[root@localhost ~]# awk -F: '{ print "用户名"$1"的uid"$3}' /etc/passwd
用户名root的uid0
用户名bin的uid1
用户名daemon的uid2
用户名adm的uid3
用户名lp的uid4
用户名sync的uid5
用户名shutdown的uid6
用户名halt的uid7
用户名mail的uid8
用户名operator的uid11
用户名games的uid12
用户名ftp的uid14
用户名nobody的uid99
用户名systemd-network的uid192
用户名dbus的uid81
用户名polkitd的uid999

  • $0 打印全部
  • $1 打印第一列
  • $n 打印第n列
  • NF 打印一行有多少列
  • $NF 打印最后一次列
  • NR 打印行号
  • NR $0 显示行号打印
  • awk -F: ‘/^bin/{print $1}’ /etc/passwd 打印bin开头的第一列
[root@localhost ~]# awk -F: '/^bin/{print $1}' /etc/passwd
bin

  • awk -F: ‘$1~/dae/{print $NF}’ /etc/passwd 匹配第一行有dae的字符然后打印此行的最后一列 ~是模糊匹配
[root@localhost ~]# awk -F: '$1~/dae/{print $NF}'  /etc/passwd
/sbin/nologin

  • awk -F: ‘NR==1{print $0}’ /etc/passwd 打印第一行,==精准匹配
    !=,>=,<=,<,>都能使用
  • awk ‘BEGIN{print 1+1}’ 用于运算,加减乘除次方都可以运算
[root@localhost ~]# awk 'BEGIN{print 1+1}' 
2

  • awk ‘BEGIN{print ‘$x’}’ 打印变量
[root@localhost ~]# awk 'BEGIN{print '$a'}' 
3

-awk ‘BEGIN{x=2;x++;print x}’

[root@localhost ~]# awk 'BEGIN{x=2;x++;print x}'
3

  • BEGIN可用于在开头插入字符
  • awk ‘END{print $0}’ p.txt 打印最后一行
[root@localhost ~]# awk 'END{print $0}' p.txt
ld

  • {FS=":"} 定义分隔符
[root@localhost ~]# awk '{FS=":"}{print $1}' p.txt
root:x:0:0:root:/root:/bin/bash
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

  • {OFS="—"} 定义两列间的字符
[root@localhost ~]# awk '{FS=":"}{OFS="---"}{print $1,$2}' p.txt
root:x:0:0:root:/root:/bin/bash---
bin---x
daemon---x
adm---x
lp---x
sync---x
shutdown---x

  • {ORS=" "} 定义每行的分隔符
[root@localhost ~]# awk '{FS=":"}{ORS="---"}{print $1,$2}' p.txt
root:x:0:0:root:/root:/bin/bash ---bin x---daemon x---adm x---lp x---sync x---shutdown x---halt x---mail x---operator x---bacsh ---bcsh ---bdsh ---loood ---lodlodlood ---lood ---ld ---[root@localhost ~]# 

  • {RS=":"} 将分隔符:定义为换行符
[root@localhost ~]# awk '{RS=":"}{print $1,$2}' p.txt
root:x:0:0:root:/root:/bin/bash 
bin 
x 
1 
1 
bin 
/bin 
/sbin/nologin

小试题

列出系统中用bash环境的用户

awk -F: '/bash/{print $1}' /etc/passwd

查看/etc/passwd这个文件,要求筛选出用户,uid和家目录,以及统计出一个共有多少个用户

awk -F: 'BEGIN{printf "%-30s%-15s%-15s\n","User","UID","Home"}{printf "%-30s%-15s%-15s\n",$1,$3,$6}''END{print "Total " NR " lines"}' /etc/passwd

写一个脚本输出所有系统中的用户和他加密后的密码

#!/bin/bash
awk -F: '$2!="!!" && $2!="*"{print $1"用户的密码是"$2}' /etc/shadow

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值