正则表达式+sed用法

什么是正则表达式?

  • 使用"一串符号"来描述有共同属性的数据
  • 使用某些符号结合相关工具对文本进行筛选,过滤,查找
基本正则列表
正则符号 含义
^ 匹配行首
$ 匹配行尾
[ ] 集合,匹配集合中任意单个字符
[x-y] 匹配连续的字符串范围
[^] 对集合取反
. 匹配任意单个字符(空格)
* 匹配前一个字符任意次数(0次) [*不允许单独使用](空格,空行)

.*

匹配多个任意字符
\ 匹配转义后的字符串
\n 通过\1至\9调用保留空间中的内容
\{n,m\} 匹配前一个字符n到m次
\{n\} 匹配前一个字符n次
\{n,\} 配前一个字符n次及以上
\( \ ) 保留,有复制功能

egrep过滤工具

文本处理顺序

  • 以行为单位,逐行进行处理
  • 默认只输出与表达式相关匹配的文本行

基本用法:

  • 格式1:  egrep  [选项] '正则表达式'   文件...
  • 格式2:  前置命令 | egrep  [选项]  '正则表达式'

常用命令选项:

  • -i  :  忽略字母大小写
  • -v :  条件取反
  • -c :  统计匹配的行数
  • -q :  静默,无任何输出,一般用于检测  ---------看$?返回值,0为匹配,非0则无匹配
  • -n :  显示匹配结果所在的行号
  • --color :  标红显示匹配字串

grep过滤工具

  • 根据字串符模式提取文本
  • 支持正则表达式
  • 匹配模式最好加上双引号""

基本用法:

  • 格式:  grep  [选项]  '匹配模式'  文本文件...

常用命令选项:

  • -i :  忽略大小写
  • -v : 取反匹配
  • -n : 显示行号
  • -q : 静默不输出
  • -E : 支持扩展正则
  • -o :  仅显示匹配内容,不显示全行所有内容
  • -w : 显示匹配内容,显示全行所有内容

[root@proxy mnt]# head -5 /etc/passwd > /mnt/test   ##以test为素材
[root@proxy mnt]# cat test
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
[root@proxy mnt]# grep root test   ##查找有root的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep ^root test   ##查找以root开头的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep bash$ test   ##查找以bash结尾的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep "[ro]" test   ##查找字母r或者o的行
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


  [ ] 范围内单字匹配

  • 匹配指定字符集合内的任何一个字符
  • [ ] 内加^可取反
[ ] 集合用法
示例 说明
[alc45_?] 匹配 a   l   c   4   5   _   ?
[a-z] 匹配任意小写字母
[A-Z] 匹配任意大写字母
[0-9] 匹配任意数字
[a-Z0-9] 匹配任意字母或数字
[^A-Z ] 匹配包含非大写字母的行
^[^a-z] 匹配不以小写字母开头的行

[root@proxy mnt]# grep "[a-z]" test   ##查找所有小写字母
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
[root@proxy mnt]# grep "[A-Z]" test    ##查找所有大写字母 素材内无大写所以无匹配.
[root@proxy mnt]# grep "[0-9]" test    ##查找所有数字
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
[root@proxy mnt]# grep "[a-Z]" test      ##查找所有字母
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
[root@proxy mnt]# grep "[^ro]" test     ##查找r或者o之外的内容
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
[root@proxy mnt]# grep "[^0-9]" test      ##查找数字之外的内容
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


[root@proxy mnt]# vim  test          ##给test文件添加几行,包括空格及空行
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
rt
rot
roooooooot
rooot


[root@proxy mnt]# grep  "." test   ##查找任意字符,发现空格也匹配
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
rt
rot
roooooooot
rooot
 
[root@proxy mnt]# grep  ".*" test  ##查找任意字符,发现空格及空行也匹配
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
rt
rot
roooooooot
rooot
 

[root@proxy mnt]# grep  "roo." test   ##找root后面任意1个字符的行
root:x:0:0:root:/root:/bin/bash
roooooooot
rooot
[root@proxy mnt]# grep  "ro.." test   ##找ro后面任意2个字符的行
root:x:0:0:root:/root:/bin/bash
roooooooot
rooot
[root@proxy mnt]# grep  "r..." test   ##找r后面任意3个字符的行
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
roooooooot
rooot
[root@proxy mnt]# grep "ro*t" test    ##查找rot,其中字母o可以出现任意次,零次也行
root:x:0:0:root:/root:/bin/bash
rt
rot
roooooooot
rooot
[root@proxy mnt]# grep "ro\{1,2\}t" test  ##o出现了1~2次
root:x:0:0:root:/root:/bin/bash
rot
[root@proxy mnt]# grep "ro\{3,5\}t" test  ##o出现了3~5次
rooot
[root@proxy mnt]# grep "ro\{3,8\}t" test  ##出现了3~8次
rooooooooto
rooot
[root@proxy mnt]# grep "ro\{1,8\}t" test   ##出现了1~8次
root:x:0:0:root:/root:/bin/bash
rot
roooooooot
rooot
[root@proxy mnt]# grep "ro\{2\}t" test   ##o出现了2次
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep "ro\{2,\}t" test  ##o出现了2次及3次以上
root:x:0:0:root:/root:/bin/bash
roooooooot
rooot
[root@proxy mnt]# grep "ro\{3,\}t" test   ##o出现了3次及3次以上
roooooooot
rooot
[root@proxy mnt]# grep  "\(0:\)\{2\}" test  ##查找0:0:
root:x:0:0:root:/root:/bin/bash

扩展正则

扩展正则列表
正则符号   含义
+ 最少匹配前一个字符1次
? 最多匹配前一个字符1次
{n,m} 匹配n到m次
() 组合为整体,保留(与正则表达式带括号的效果一样)
| 或者
\b 单词边界
[root@proxy mnt]# grep "\(0:\)\{2\}" test  ##查找0:0:两次
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep "ro\{2\}t" test      ##查找前一个字符出现2次
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# grep -E "ro{2}t" test   ##效果同上
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# egrep  "ro{2}t" test    ##效果同上
root:x:0:0:root:/root:/bin/bash 
[root@proxy mnt]# egrep  "ro{1,3}t" test   ##查找rot,其中o可以出现1次到3次
root:x:0:0:root:/root:/bin/bash
rot
rooot
[root@proxy mnt]# grep  "ro\{1,\}t" test   ##查找rot,其中o可以出现1次及1次以上
root:x:0:0:root:/root:/bin/bash
rot
roooooooot
rooot
[root@proxy mnt]# egrep  "ro{1,}t" test   ##效果同上
root:x:0:0:root:/root:/bin/bash
rot
roooooooot
rooot
[root@proxy mnt]# egrep  "ro+t" test   ##查找rot其中o最少可以出现1次
root:x:0:0:root:/root:/bin/bash
rot
roooooooot
rooot
[root@proxy mnt]# grep  "ro\{0,1\}t" test   ##查找rot,其中o可以出现0次到1次
rt
rot
[root@proxy mnt]# egrep  "ro{0,1}t" test   ##效果同上
rt
rot
[root@proxy mnt]# egrep  "ro?t" test   ##查找rot,其中o可以出现1次或0次
rt
rot
[root@proxy mnt]# egrep "root|bin" test  ##查找有root或者bin的行
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
[root@proxy mnt]# egrep "^root|^bin" test     ##查找以root开头或者以bin开头的行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@proxy mnt]# egrep "^(root|bin)" test   ##效果同上
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

{ } 限定次数

  • 限定表达式的匹配次数
  • {n}  {n,m}  {n,}
类 型 含义 示例 说明
{n} 匹配n次 (ab){3} 匹配ababab
{n,m} 匹配n-m次 (ab){1,3} 匹配ab, abab, ababab
{n,} 匹配至少n次 (ab){2,} 匹配2个及以上连续的 ab

整体及边界匹配

类型 含义 示例 说明
\< 单词的开头 \<th 匹配以th开头的单词
\> 单词的结束 \<root\> 作用与\broot\b相同
\w 字母数字下划线 \wa 匹配xa,不匹配#a
\s 匹配空白 \sa 匹配  a,不匹配xa
\d 匹配数字 -P\da 匹配5a,不匹配xa

 \b  在匹配字母时,屏蔽字母,数字,下划线

[root@proxy mnt]# vim abc   ##以ABC作为素材
the
1the
$the*
_thea
[root@proxy mnt]# grep "the" abc   ##找有the的行
the
1the
$the*
_thea
[root@proxy mnt]# grep "the\b" abc  ##找有the且右边不能是字母数字下划线
the
1the
$the*
[root@proxy mnt]# grep "\bthe\b" abc  ##找有the且两边不能是字母数字下划线
the
$the*
[root@proxy mnt]# grep "\bthe" abc  ##找有the且左边不能是字母数字下划线
the
$the*

sed的基本用法

sed概述:

  • Stream EDitor , 流式编辑器
  • 非交互式,基于模式匹配过滤及修改文本
  • 逐行处理,并将结果输出到屏幕
  • 可实现对文本的输出,删除,替换,复制,剪切,导入,导出等各种操作
  • 支持正则表达式
     

命令格式:

  • 格式1 : 前置命令 | sed  [选项]  '(定址i符)指令'
  • 格式2 : sed  [选项]  '(定址i符)指令'   被处理的文档
  1. 定址符 : 定位哪一行(就是在哪一行去执行这个指令)
  2. 定址符可以写行号(数字)或者正则表达式

常用命令选项

  • -n :  屏蔽默认输出(默认sed会输出读取文档的全部内容)
  • -i :  直接修改文件内容(默认sed只是通过内存临时修改文件,源文件无影响)
  • -r : 启用扩展正则表达式,若与其他选项一起使用,应作为首个选项
  • -e : 指定需要的执行的sed指令,支持使用多个-e参数
  • -f : 指定需要执行的脚本文件,需要提前将sed指令写入文件中

常用指令选项

操作符 用途 指令示例
p 输出 2,4p   输出第2, 3, 4行
2p;4p  输出第2行, 第4行
d 删除 2,4d  删除第2行和第4行
s 替换 s/old/new/      将每行的第1个old替换为new
s/old/new/3    将每行的第3个old替换为new
s/old/new/g    将所有的old替换为new
  • = : 输出行号
  • "$=" 输出最后一行行号
  • ;  分隔前后两条指令
  • 替换操作的分隔"//"  可改用其他字符,键盘上1-0的特殊字符,例如:!@#$%^&*()

命令格式解析

  • 条件,可以是行号或正则表达式
  • 行号可以使用单个数字表示当前行
  • 或者3,5表示连续的多行
  • 省略条件,则默认逐行处理全部文本
  • 匹配正则时,需要使用//
  • 默认sed会将所有输出的内容都打印出来,可以使用-n屏蔽默认输出
  • 选项中可以使用-r选项,让sed支持扩展正则

输出文本练习:

[root@proxy mnt]# cat test   ##以test文件作为素材
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
[root@proxy mnt]# sed 'p' test    ##输出+默认输出,所以是每行出现2次
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed -n 'p' test   ## 输出全文
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
[root@proxy mnt]# sed -n '1p' test  ##输出第一行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# sed -n '2p' test  ##输出第二行
bin:x:1:1:bin:/bin:/sbin/nologin
[root@proxy mnt]# sed -n '3p' test   ##输出第三行
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@proxy mnt]# sed -n '1,3p' test  ##输出1-3行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@proxy mnt]# sed -n '1p;3p' test  ##输出第1行和第3行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@proxy mnt]# sed -n '1,+2p'  test  ##输出第1行以及后面2行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@proxy mnt]# sed -n '3,+1p'  test   ##输出第3行以及后面1行
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@proxy mnt]# sed -n '1~2p'  test   ##输出奇数行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed -n '2~2p'  test   ##输出偶数行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@proxy mnt]# sed -n '/root/p'  test  ##输出有root的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# sed -n '/^root/p'  test  ##输出以root开头的行
root:x:0:0:root:/root:/bin/bash
[root@proxy mnt]# free | sed -n '2p'   ##输出free指令生成的文档的第2行
Mem:        1446924       70232     1108292        8608      268400     1211636
[root@proxy mnt]# sed -rn '/root|bin/p'  test  ##输出有root或者有bin的行
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
[root@proxy mnt]# sed -n '$=' test   ##输出全文最后1行行号
5

删除文本练习:

[root@proxy mnt]# sed 'd' test   ##删除全文
[root@proxy mnt]# sed '1d' test  ##删除第1行,显示剩余行
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
[root@proxy mnt]# sed '2d' test     ##删除第2行,
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
[root@proxy mnt]# sed '5d' test      ##删除第5行
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@proxy mnt]# sed '1,3d' test     ##删除1-3行
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '3,+2d' test     ##删除第3行以及后面2行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@proxy mnt]# sed '/bash$/d' test   ##删除以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
[root@proxy mnt]# sed '1d;3d' test      ##删除第1行和第3行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '1~2d' test      ##删除奇数行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@proxy mnt]# sed '2~2d' test      ##删除偶数行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '$d' test    ##删除全文最后1行
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@proxy mnt]# sed '/var/!d' test    ##不删除有var的行
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

替换练习:

[root@proxy mnt]# vim hihi  ##以hihi作为素材
2017 2011 2018
2017 2017 2024
2017 2017 2017
[root@proxy mnt]# sed 's/2017/xxxx/' hihi  ##将所有行的第1个2017替换成xxxx
xxxx 2011 2018
xxxx 2017 2024
xxxx 2017 2017
[root@proxy mnt]# sed 's/2017/xxxx/2' hihi  ##将全文的第2列的2017替换成xxxx
2017 2011 2018
2017 xxxx 2024
2017 xxxx 2017
[root@proxy mnt]# sed 's/2017/xxxx/g' hihi  ##将全文的2017替换成xxxx
xxxx 2011 2018
xxxx xxxx 2024
xxxx xxxx xxxx
[root@proxy mnt]# sed '2s/2017/xxxx/' hihi  ##将第2行的第1个2017替换成xxxx
2017 2011 2018
xxxx 2017 2024
2017 2017 2017
[root@proxy mnt]# sed '3s/2017/xxxx/2' hihi  ##将第3行的第2个2017替换成xxxx
2017 2011 2018
2017 2017 2024
2017 xxxx 2017
[root@proxy mnt]# sed '3s/2017//2' hihi   ##潜在的删除功能,将第3行的第2个2017替换成空
2017 2011 2018
2017 2017 2024
2017 2017
[root@proxy mnt]# sed 's/2024/xxxx/p' hihi  ##将所有行的2024替换成xxxx
2017 2011 2018
2017 2017 xxxx
2017 2017 xxxx
2017 2017 2017

1.如何把/bin/bash换成/sbin/sh?


[root@proxy mnt]# cat test  ##以test作为素材
root:x:0:0:root:/root:/bin/bash

[root@proxy mnt]# sed  's/\/bin\/bash/\/sbin\/sh/'   test  ##正常替换,繁琐
root:x:0:0:root:/root:/sbin/sh
[root@proxy mnt]# sed   's#/bin/bash#/sbin/sh#'    test   ##修改替换符,简洁
root:x:0:0:root:/root:/sbin/sh 


2.删除文件中每行的第二个、最后一个字符


[root@proxy mnt]# cat nns    ##以nns文件作为素材
Hello the world
ni hao ma beijing

[root@proxy mnt]# sed 's/.//2' nns    ##删除全文第2个字符
Hllo the world
n hao ma beijing
[root@proxy mnt]# sed 's/.$//' nns    ##删除全文最后1个字符
Hello the worl
ni hao ma beijin
[root@proxy mnt]# sed 's/.//2;s/.$//' nns   ##组合在一起就是删除全文的第2个和最后1个字符
Hllo the worl
n hao ma beijin


3.将文件中每行的第一个、倒数第1个字符互换


[root@proxy mnt]# cat abc   ##以abc 文件作为素材
abc
xyz

[root@proxy mnt]# sed -r 's/(a)(b)(c)/\3\2\1/' abc    ##替换abc为cba
cba
xyz

[root@proxy mnt]# sed -r 's/(^.)(.*)(.$)/\3\2\1/' abc   ##将全文每行的第一个、倒数第1个字符互换
cba
zyx


4.删除文件中所有的数字


[root@proxy mnt]# cat nns  ##以nns作为素材
He4llo t5he world
nI hao m7A Beijing
[root@proxy mnt]# sed -i 's/[0-9]//g' nns    ##删除全文数字
[root@proxy mnt]# cat nns
Hello the world
nI hao ma beijing


5.为文件中每个大写字母添加括号


[root@proxy mnt]# cat nns   ##以nns作为素材
Hello the world
nI hao mA Beijing
[root@proxy mnt]# sed -r 's/([A-Z])/(\1)/g' nns   ##添加小括号
(H)ello the worl(D)
n(I) hao m(A) b(E)ijing
[root@proxy mnt]# sed -r 's/([A-Z])/{\1}/g' nns    ##添加花括号
{H}ello the worl{D}
n{I} hao m{A} b{E}ijing
[root@proxy mnt]# sed -r 's/([A-Z])/[\1]/g' nns    ##添加中括号
[H]ello the worl[D]
n[I] hao m[A] b[E]ijing


编写脚本,实现ftp服务的安装过程到使用,要支持匿名上传(从pub目录)

[root@proxy mnt]# vim test03.sh
#!/bin/bash
#这是一个简单的ftp服务
if [ "$USER" != "root" ];then
echo "你不是管理员,没有权限哦!"
exit 2
fi
rpm -q vsftpd
if [ $? -ne 0 ];then
yum -y install vsftpd  &> /dev/null 
sed -i '/^#anon_upl/s/#//'  /etc/vsftpd/vsftpd.conf
systemctl restart vsftpd
systemctl enable  vsftpd  &> /dev/null
chmod 777 /var/ftp/pub
#setenforce 0               ##安装有防火墙就需要这2行
#systemctl stop  firewalld   
else
echo "请稍等..."
sed -i '/^#anon_upl/s/#//'  /etc/vsftpd/vsftpd.conf
systemctl restart vsftpd
systemctl enable  vsftpd  &> /dev/null
chmod 777 /var/ftp/pub
#setenforce 0               ##安装有防火墙就需要这2行
#systemctl stop  firewalld   
fi

sed文本块处理

sed指令
操作符 用途 指令示例
i 行前追加 2iYY   在第2行之前添加文本行 "YY"
4,7iYY  在第4-7行的每一行前添加文本行
a 行后追加 2aYY  在第2行之后添加文本
/^XX/aYY  在以XX开头的行之后添加文本
c 替换当前行 2cYY   将第2行的内容修改为 "YY"

处理多行文本

修改后的文本有多行时

  • 以换行符 \n 分隔
  • 或者,使用 \ 强制换行 

a行后追加练习: 

[root@proxy mnt]# sed 'a666' test   ##所有行后添加一行666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
666
[root@proxy mnt]# sed '1a 666' test   ##第1行后添加一行666
root:x:0:0:root:/root:/bin/bash
666
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
[root@proxy mnt]# sed '2,3a 666' test  ##第2~3行后添加一行666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '/bin/a 666' test  ##在有bin的行后添加一行666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
666
[root@proxy mnt]# sed '/^bin/a 666' test  ##以bin开头的行后添加一行666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
666
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
[root@proxy mnt]# sed -e '2a 666' -e '4a 666'  test  ##第2行和第4行行后添加666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

i行前追加练习:

[root@proxy mnt]# sed 'i 666' test  ##所有行前添加一行666
666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '2,+1i 666' test  ##第2~3行前添加一行666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
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
[root@proxy mnt]# sed '/root/i 666' test  ##有root的行前添加一行666
666
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
[root@proxy mnt]# sed '/^root/i 666' test  ##以root开头的行添加一行666
666
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
[root@proxy mnt]# sed '2i 666' test    ##第2行前添加一行666
root:x:0:0:root:/root:/bin/bash  
666
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

c替换当前行练习:

[root@proxy mnt]# sed 'c 666' test  ##替换全文所有行为666
666
666
666
666
666
[root@proxy mnt]# sed '4c 666' test  ##替换第四行为666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@proxy mnt]# sed '$c 666' test   ##替换最后一行为666
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
666
[root@proxy mnt]# sed '/root/c 666' test  ##找有root的行替换为666    
666
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
[root@proxy mnt]# sed '/^bin/c 666' test  ##以bin开头的行替换为666
root:x:0:0:root:/root:/bin/bash
666
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

sed高级应用

导入导出操作

  • r 动作应结合 -i 选项才会存入,否则只输出
  • w 动作以覆盖的方式另存为新文件
操作符 用途 指令示例
r 读取文件 3r  b.txt  在第3行下方添加文件b.txt
4,7r  b.txt  在第4-7行后添加文件b.txt
w 保存到文件 3w  c.txt  将第3行另存为文件c.txt
4,7w  c.txt 将第4-7行另存为文件c.txt

!取反操作

用途

  • 根据定址条件取反

示例

  • 列出不使用bash的用户账号记录
[root@proxy mnt]# sed -n '/bash$/!p' /etc/passwd  ##输出不是以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
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
......

sed综合脚本应用

问题

  • 找到使用bash作登录Shell的本地用户
  • 列出这些用户的shadow密码记录
  • 按每行“用户名 --> 密码记录”保存到getupwd.log,如图所示

方案:

  1. 先用sed工具取出登录Shell为/bin/bash的用户记录,保存为临时文件/tmp/urec.tmp,并计算记录数量
  2. 再结合while循环遍历取得的账号记录,逐行进行处理
  3. 针对每一行用户记录,采用掐头去尾的方式获得用户名、密码字串
  4. 按照指定格式追加到/tmp/getuupwd.log文件
  5. 结束循环后删除临时文件,报告分析结果
[root@proxy mnt]# vim ./getupwd.sh  
#/bin/bash
A=$(sed -n '/bash$/s/:.*//p' /etc/passwd)   ## 提取符合条件的账号记录
for i in  $A                                ##遍历账号记录
do
    pass1=$(grep $i /etc/shadow)
    pass2=${pass1#*:}
    pass=${pass2%%:*}
    echo  "$i   --> $pass"
done
[root@proxy mnt]# bash getupwd.sh    ##效果如图所示!!!

发布了11 篇原创文章 · 获赞 10 · 访问量 1818

猜你喜欢

转载自blog.csdn.net/weixin_45971087/article/details/103850171