shell中的文本处理
- grep 文本过滤命令
- sed 行编辑器
- awk 报告生成器
(一) grep 文本过滤命令
- 介绍:grep 命令是一种强大的文本搜索工具,根据用户制定的“模式”对目标文本进行匹配检查,打印匹配到的行;过滤条件是由正则表达式或者字符及基本文本字符所编写的;
- 用法(usage):
grep 匹配条件 处理文件
grep root passwd ##打印所有含有root的行
grep ^root passwd ##打印root开头的行
grep root$ passwd ##打印root结尾的行
grep -i ^root passwd ##打印以root开头的行;-i不区分大小写
grep -i -E “^root|root$” passwd ##打印以root开头或者以root结尾的行
grep -i -E -v “^root|root$” passwd ##过滤掉以root开头或者以root结尾
的行;-E 扩展正则表示式;-v 反向过滤,把不符合的屏蔽;
grep -E “^root | root$” passwd <=> egrep “^root| root$” passwd
示例:
1、要求输出中间含有 root 的行;
A: grep -v -i -E "^root|root$" passwd | grep root
B: grep -i root passwd | grep -v -i -E "^root|root$"
2 、用脚本实现在系统当中找到能登陆系统的用户;
vim /mnt/show_loginuser.sh //编辑内容
#!/bin/bash
SHELL=$(echo `grep -v nologin /etc/shells`| sed 's/ /|/g')
grep -E "$SHELL" /etc/passwd | cut -d :-f 1
sh /mnt/check_user.sh //运行脚本
测试:
useradd -s /bin/tcsh user1 //创建新用户 sh /mnt/show_loginuser.sh //再次执行脚本,会多出userq1用户
-
grep 中的正则表达式:
^root root$ 'r....t' 'r.....' '.....t'
* | 字符出现0-任意一次 |
---|---|
? | 字符出现0-1次 |
+ | 字符出现1-任意次 |
{2} | 字符出现2次 |
{m,n} | 字符出现m次,最多出现n次 |
{m,} | 字符至少出现m次 |
\> | 标识匹配字符精确,防止字符扩展;相当于一堵墙 |
\ | 转义 ;加上-E 可以不用添加\字符 |
//应用:
grep 'r..t' test //找到r和t之间只有2个字符
grep 'r...t' test
grep 'r....t' test
grep 'r*t' test //找到t前面有n个r的字符的关键词
grep -E 'r*t' test
grep -E 'ro*t' test //找到r和t之间o出现0到任意次的关键词
grep -E 'ro?t' test //找到r和t之间o出现0到1次的关键词
grep -E "ro+t" test //找到r和t之间o出现1到任意次的关键词
grep -E 'ro{1,}t' test //找到r和t之间o出现1到3次的关键词
grep -E 'ro{1,3}t' test //找到r和t之间o出现1到3次的关键词
grep -E '(root){2,}' test //找到至少出现2次root的关键词
grep -E '(root){1,3}' test //找到出现1次到2次root的关键词
grep -E 'r....' test //找到r后面有4个任意字符的关键词
grep -E 'r....\>' test //找到r后面只有4个任意字符的关键词
grep -E '\<....t' test //找到t前面只有4个任意字符的关键词
(二) sed 行编辑器
用来操作ASCII的纯文本;
处理时,把当前处理的行储存在临时缓冲区中,成为“模式空间”可以制定仅仅处理那些行;符合模式条件处理,不符合条件的不予处理;
处理完成之后把缓冲区的内容送往屏幕;
接着处理下一行,这样不断重复,直至文件末尾;
- sed 命令的格式:
sed [参数] ‘命令’ file(s) - sed 对字符的处理:
p 显示
d 删除
a 添加
c 替换
w 写入
i 插入
(1)p(显示)模式操作:
sed -n '/\:/p' fstab //显示含有:的行
sed -n '/^#/p' fstab //显示以#开头的行
sed -n '/^#/!p' fastab //不显示以#开头的行
sed -n '2,6p' fstab //显示2到6行内容
sed -n '2,6!p' fstab //不显示2到6行内容
sed -n '2p;6p' fstab //显示第2行和第6行
**注:多个策略用-e连接**
脚本示例:
编写一个脚本,要求当执行脚本时,创建文件userfile中存在的用户名,并修改密码;
vim userfile //用户名存在的文件
user1
user2
user3
vim passfile //用户名所对应的密码
123
123
123
vim /mnt/create_userfile.sh
#!/bin/bash
MAX_LINE=`wc -l $1 | cut -d " " -f 1`
for LINE_NUM in `seq 1 $MAX_LINE`
do
USERNAME=`sed -n "${LINE_NUM}p" $1`
PASSWORD=`sed -n "${LINE_NUM}p" $2`
useradd $USERNAME
echo $PASSWORD | passwd --stdin $USERNAME
done
sh /mnt/create_userfile.sh userfile passfile
(2)d模式(删除delete)
[root@desktop mnt]# cat -n fstab | sed -e '2d;6d' //删除第二行和第6行
[root@desktop mnt]# cat -n fstab | sed -e '2,6d' //删除第二行到第六行
[root@desktop mnt]# cat fstab | sed -e '/^#/d' //删除以#开头的行
[root@desktop mnt]# sed -e '/^$/d' fstab //删除空行
[root@desktop mnt]# sed -e '/^$/d;/^#/d' fstab //删除以#开头的行和空行
[root@desktop mnt]# sed '/^UUID/d' fstab //删除以UUID开头的行
[root@desktop mnt]# sed '/^UUID/!d' fstab //不删除UUID开头的行
[root@desktop mnt]# sed '/0$/d' fstab //删除以0结尾的行
(3)a模式(添加)
[root@desktop mnt]# sed '/hello/aworld' westos ##在hello之后添加字符word
hello
world
[root@desktop mnt]# sed 's/hello/hello world/g' westos ##全文替换hello为hello world;如果不添加g那么模式替换每行的第一个匹配字符
hello world
[root@desktop mnt]# sed '/hello/aworld\nwestos' westos ##在hello行后添加world和westos两行内容
hello
world
westos
(4)i模式(插入)
[root@desktop mnt]# sed '/hello/iworld\nwestos' westos ##在hello行前添加world和westos两行内容;
world
westos
hello
这里可以看到a模式和i模式的区别:a模式在指定行后添加内容;i模式在指定行前插入内容
(5)c模式(改)
[root@client mnt]# cat westos
hello
[root@client mnt]# sed '/hello/chello word' westos
hello word
(6)w模式(写)
sed -n '/bash$/wfile' passwd //处理一行,写一行;-n出现一次
(7)其他用法
= 表示加入行号;
6r 表示将文件写入第6行下一行;
N 表示每一行添加换行符
G 表示每行后面插入空行
-n '$p' 显示最后一行
-i 改变原文件的内容
示例:
脚本编写:安装appache,并且改变它的端口;
vim /mnt/install_appache.sh
#!/bin/bash
yum install httpd.x86_64 -y &> /dev/null
sed "/^Listen/cListen $1" -i /etc/httpd/conf/httpd.conf
echo -e "\033[5m\033[46mListen has changed\033[0m"
echo "Now,Listen is $1!"
systemctl restart httpd
sh /mnt/install_appache.sh 77
(三)awk 报告生成器
-
awk 处理机制:awk 会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后以行做一些总结性质的工作,在命令格式上分别体现如下:
BEGIN{}:读入第一行文本之前执行,一般用来初始化操作;
{}:逐行处理,逐行读入文本执行相应的处理,是最常见的编辑指令;
END{}:处理完最后一行文本之后执行,一般用来输出处理结果; -
awk 基本用法:
awk -F ":" '{print $1}' passwd ##以:为分隔符,输出passwd文件的第一列 awk -F ":" 'BEGIN{print "NAME"}{printNR;print }END{print "END"}' passwd ##输出所有passwd所有内容,并在第一行前加NAME,最后一行加END awk '/bash$/{print}' passwd ##输出passwd所有以bash结尾的行 awk -F ":" '/bash$/{print $1}' passwd ##输出passwd以bash结尾的所有行的第一列 awk '/^[a-o]/{print}' passwd ##输出passwd中以a-o开头的所有行 awk '/^[^a-o]/{print}' passwd ##输出passwd中除了以a-o开头的所有行 awk '/^r/&&/bash$/{print}' passwd ##输出以r开头并且以bash为结尾的所有行 awk '/^r/||/^b/{print}' passwd ##输出以r开头或者以b开头的所有行 awk -F ":" '$1!~/^r/{print}' passwd ##输出以:为分隔符,除了以r开头的所有行的第一列 awk -F ":" '{print NR,$0}' passwd ##输出每一行的内容,并在每一行的第一列前加上行号
示例:
1、显示可以登陆系统的用户的个数;
awk -F ":" '\$6!~/^\/home/&&/bash\$/{print $1}' /etc/passwd //显示可以登陆的用户
awk -F ":" 'BEGIN{n=0}\$6!~/^\/home/&&/bash\$/{n++}END{print n}' /etc/passwd //统计个数
2、打印出passwd文件的行数
[root@desktop mnt]# awk 'BEGIN{n=0}//{n++}END{print n}' passwd
3、显示主机的ip
ifconfig eth0 | awk '/inet\>/{print $2}'