sed基本用法、

###################################################

shell  脚本编程

一、sed基本用法

1.sed命令解析

1sed工具概述

stream editor  流式编辑器

--非交互,脚本里用sed,命令行用vim。(vim交互式,进出都需对应模式)

    --逐行处理,并将结果输出到屏幕。每次只读一行,大文本处理快。

########################################

clone-vm7   克隆虚拟机

read -p  “Enter  number:”  num

1. 快速建立前端盘:qemu-img  create -f   qcow2  -b   /var/lib/libvirt/images//rhel7.qcow2     /var/lib/libvirt/images/rhel7 -$num.qcow2              

2.  复制配置文件:  cp    ../images/rhel7.xml       ../images/rhel7-$num.xml  

3. 修改配置文件:   <name,UUID,source,MAC,disk>   -->   sed    ../images/rhel7-$num.xml  

4. 定义新虚拟机:   virsh  define  ../images/rhel7-$num.xml

########################################

2sed文本处理工具的用法格式:

用法1sed    [选项]     '条件指令'     文件

用法2: 前置命令  | sed    [选项]    '条件指令'

定址符

########################################

条件:行号、/正则/    指令:增删改查

选项:-n   屏蔽默认全部的输出   (sed  默认会把整个文件输出)

-i   直接修改文件内容(sed默认不改源文件,把修改后的结果输出到屏幕上,脚本要上加i

-r 启用扩展正则(默认不启用),若与其他选项一起使用,应作为首个选项

-{}:可组合多个命令,以分号分隔

#sed   -n    '3p'   /etc/hosts      /只输出第3

sed   -n    '/正则/p'    文件

      #sed   -n    '/[0-9]/p'   /etc/hosts

########################################

指令:

sed   ‘3d;11d;55d’   /etc/hosts

d 删除行  'd '   没条件则匹配所有,全部删除; '3d'  删除第三行

p  打印行/输出行          #sed  '3p'   /etc/hosts       /多了第三行的复制版

s   修改   字符串替换    s///3   第三个老的,g为所有

替换操作的分隔( /)  可改用其他字符,如#&等,便于修改文件路径

########################################

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

分两次替换操作,第一次替换掉第2个字符,第二次替换掉最后一个字符:

[root@svr5 ~]# sed 's/.//2;s/.$//' nssw.txt

2)将文件中每行的第一个、第二个字符互换

每行文本拆分为1个字符2个字符剩下的所有字符三个部分,然后通过替换操作重排顺序为“2-1-3”

[root@svr5 ~]# sed -r 's/^(.)(.)(.*)/\2\1\3/' nssw.txt

3)删除文件中所有的数字、行首的空格

因原文件内没有数字,行首也没有空格,这里稍作做一点处理,生成一个新测试文件:

[root@svr5 ~]# sed 's/o/o7/;s/l/l4/;3,5s/^/  /' nssw.txt > nssw2.txt

nssw2.txt文件为例,删除所有数字、行首空格的操作如下:

[root@svr5 ~]# sed -r 's/[0-9]//g;s/^( )+//' nssw2.txt

4)为文件中每个大写字母添加括号

使用“&”可调用s替换操作中的整个查找串,所以可参考下列操作解决:

[root@svr5 ~]# sed 's/[A-Z]/(&)/g' nssw.txt

########################################

2)修改IP地址的网段部分,主机地址不变。

直接修改网卡eth0的配置文件,检查原有的配置内容:

[root@svr5 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0

IPADDR=192.168.4.4

TYPE=Ethernet

若希望将IP地址192.168.4.4修改为172.16.16.4,则应该定位到“IPADDR”所在的行,执行相应的替换(仅测试,尚未修改):

[root@svr5 ~]# sed '/^IPADDR/s/192.168.4.4/172.16.16.4/' /etc/sysconfig/network-scripts/ifcfg-eth0 | grep "^IPADDR"

PADDR=172.16.16.4

要求只修改网段地址时,可以利用扩展正则表达式的 \1\2……等调用,分别对应此前第1个、第2个、…… ()包围的表达式所匹配的内容。

所以上述操作可以改为如下(启用扩展匹配应添加 -r 选项):

[root@svr5 ~]# sed -r -i '/^IPADDR/s/192.168.4.(.*)/172.16.16.\1/'

/etc/sysconfig/network-scripts/ifcfg-eth0

确认修改结果:

[root@svr5 ~]# grep "^IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0

IPADDR=172.16.16.4

再改回去:

[root@svr5 ~]# sed -r -i '/^IPADDR/s/172.16.16.(.*)/192.168.4.\1/'

/etc/sysconfig/network-scripts/ifcfg-eth0

[root@svr5 ~]# grep "^IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0

IPADDR=192.168.4.4

3)调整httpd服务配置,更改网站根目录

由于需要替换的字符串中有 / ,为了避免与sed替换操作的分隔混淆,可以使用其他字符作为替换分隔,比如可改用“s#old#new#”的方式实现替换:

[root@svr5 ~]# sed -i 's#/var/www/html#/opt/wwwroot#'

/etc/httpd/conf/httpd.conf

[root@svr5 ~]# grep "^DocumentRoot" /etc/httpd/conf/httpd.conf

DocumentRoot "/opt/wwwroot"

若要恢复,可再改回去:

[root@svr5 ~]# sed -i 's#/opt/wwwroot#/var/www/html#'

 /etc/httpd/conf/httpd.conf

[root@svr5 ~]# grep "^DocumentRoot" /etc/httpd/conf/httpd.conf

DocumentRoot "/var/www/html"

########################################

通过yum安装vsftpd软件包

  • 修改vsftpd服务配置,开启匿名上传
  • 调整/var/ftp/pub目录权限,允许ftp写入
  • 启动vsftpd服务,并设置开机自运行

步骤二:编写anonftp.sh脚本,用来装配匿名FTP服务

1)任务需求及思路分析

vsftpd服务的安装、改目录权限、起服务等操作可以直接写在脚本中。

修改vsftpd.conf配置的工作可以使用sed命令,根据默认配置,只需要定位到以#anon开头的行,去掉开头的注释即可。

2)根据实现思路编写脚本文件

[root@svr5 ~]# vim anonftp.sh

#!/bin/bash

yum -y install vsftpd                      //安装vsftpd软件

cp /etc/vsftpd/vsftpd.conf{,.bak}               //备份默认的配置文件

sed -i "/^#anon/s/^#//" /etc/vsftpd/vsftpd.conf            //修改服务配置

chown ftp /var/ftp/pub                    //调整目录权限

/etc/init.d/vsftpd restart             //启动服务

chkconfig vsftpd on       //设为自动运行

[root@svr5 ~]# chmod +x anonftp.sh

3)验证、测试脚本

运行脚本anonftp.sh

[root@svr5 ~]# ./anonftp.sh

Complete!关闭 vsftpd:    [失败]

vsftpd 启动 vsftpd:     [确定]

使用ftp登录服务,测试是否可以上传:

[root@svr5 ~]# ftp localhost     //本机访问测试

Connected to localhost.localdomain.220 (vsFTPd 2.0.5)530 Please login with USER and PASS.530 Please login with USER and PASS.KERBEROS_V4 rejected as an authentication

typeName (localhost:root): ftp  //匿名登录331

Please specify the password.Password:230 Login successful.Remote system type is UNIX.Using binary mode to transfer

 files.ftp> cd pub  //切换到 pub/ 目录250

Directory successfully changed.ftp> put install.log   //上传当前目录下的

install.log 文件local: install.log remote: install.log227 Entering Passive Mode (127,0,0,1,192,127)150 Ok to send data.226 File receive OK.33139 bytes sent in 0.0065 seconds (5e+03 Kbytes/s)

ftp> quit  //断开FTP连接221 Goodbye.

查看/var/ftp/pub新上传的文件:

[root@svr5 ~]# ls -lh /var/ftp/pub/总计 36K-rw------- 1 ftp ftp 33K 12-13 18:25 install.log

3 案例3sed多行文本处理

3.1 问题

本案例要求使用sed工具来完成下列任务操作:

  • 修改主机名配置文件
  • 修改hosts文件,添加两条映射记录:192.168.4.5 svr5.tarena.comsvr5,还有119.75.217.56www.baidu.com

3.2 方案

sed工具的多行文本处理操作:

  • i:在指定的行之前插入文本
  • a:在指定的行之后追加文本 
  • c:替换指定的行

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:修改主机名配置文件

1)确认修改前的配置

[root@svr5 ~]# cat /etc/sysconfig/network

  NETWORKING=yes   HOSTNAME=svr5.tarena.com

2)使用sed修改主机名配置所在行的内容(c整行替换)

[root@svr5 ~]# sed  '/^HOSTNAME/cHOSTNAME=mysvr.tarena.com'    /etc/sysconfig/network

步骤二:修改hosts文件,添加新的记录

1)确认修改前的配置

[root@svr5 ~]# cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         

localhost localhost.localdomain localhost6 localhost6.localdomain6

2)使用sed修改hosts文件,添加两行新纪录(a追加)

[root@svr5 ~]# sed  -i  '$a192.168.4.5  svr5.tarena.com svr5\> 119.75.217.56 www.baidu.com' /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         

localhost localhost.localdomain localhost6 localhost6.localdomain6192.168.4.5  svr5.tarena.com svr5119.75.217.56  www.baidu.com

4 案例4sed综合脚本应用

4.1 问题

本案例要求编写脚本getupwd.sh,实现以下需求:

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

 

4.2 方案

基本思路如下:

  1. 先用sed工具取出登录Shell/bin/bash的用户记录,保存为临时文件/tmp/urec.tmp,并计算记录数量
  2. 再结合while循环遍历取得的账号记录,逐行进行处理
  3. 针对每一行用户记录,采用掐头去尾的方式获得用户名、密码字串
  4. 按照指定格式追加到/tmp/getuupwd.log文件
  5. 结束循环后删除临时文件,报告分析结果

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写getupwd.sh脚本

[root@svr5 ~]# vim ./getupwd.sh  

#/bin/bash

> /tmp/getupwd.log   ## 创建空文件

sed -n '/:\/bin\/bash$/w /tmp/urec.tmp' /etc/passwd   ## 提取符合条件的账号记录

UNUM=$(egrep -c '.' /tmp/urec.tmp)  ## 取得记录个数

while [ ${i:=1} -le $UNUM ]    ## 从第1行开始,遍历账号记录

do    UREC=$(sed -n "${i}p" /tmp/urec.tmp) ## 取指定行数的记录    

NAME=${UREC%%:*}     ## 截取用户名(记录去尾)    

PREC=$(sed -n "/^$NAME:/p" /etc/shadow) ## 查找与用户名对应的密码记录    

PASS=${PREC#*:}      ## 掐头    

PASS=${PASS%%:*}     ## 去尾,只留下密码记录    

echo "$NAME --> $PASS" >> /tmp/getupwd.log   ## 保存结果    

let i++      ## 自增1,转下一次循环

done

/bin/rm -rf /tmp/urec.tmp   ## 删除临时文件

echo "用户分析完毕,请查阅文件 /tmp/getupwd.log" ## 完成后提示

[root@svr5 ~]# chmod +x ./getupwd.sh

步骤二:测试、验证执行结果

[root@svr5 ~]# ./getupwd.sh     用户分析完毕,请查阅文件 /tmp/getupwd.log

[root@svr5 ~]# less /tmp/getupwd.log root -->

$6$IWgMYmRACwdbfwBo$dr8Yn983nswiJVw0dTMjzbDvSLeCd1GMYjbvsDiFEkL8jnXOLcocBQypOCr4C6BRxNowIxjh6U2qeFU0u1LST/zengye -->

$6$Qb37LOdzRl5995PI$L0zTOgnhGz8ihWkW81J.5XhPp/l7x2./Me2ag0S8tRndCBL9nIjHIKkUKulHxJ6TXyHYmffbVg

UT6pbSwf8O71clamav --> !!mysql --> !!abc --> !!

yinshixiong

      正则表达式

^ 开始

$ 结尾

[ ] 集合之一

[0-9]==[0123456789]

[a-f4-7]==[abcdef4567]

[a-Z]==[a-zA-Z]

[^abc]除了abc

. 代表任意单个符号 每次只能代表一个

..

...

.* 代表匹配任意所有

2\{2,5\} 2\{2,\}

a\{3\}

cat abcdefgskaldkjfkla;jd

sed /IPADDR/s

sed 's//172.16.0.\2/' a.txt

([0-9]{1-3}.){3}([0-9]{1})

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

sed -a

[root@17:04:35 /opt/shell05 397]#sed '2a XXX' a.txt

hello the world

the time always go

XXX

filesystem the

[root@17:04:52 /opt/shell05 398]#sed '2i XXX' a.txt

hello the world

XXX

the time always go

filesystem the

[root@17:05:02 /opt/shell05 399]#

sed '/root/s/xxx/xxx1/g' 先进入到有/root/这一行然后再进行其他操作

********************************sed '/root/a xxx ' /etc/passwd 可以是路径或者其他关键词*******************************

###########################################################################################################################

ab

abb

abbb

ac

ttt

#grep "ab*" txt

ab

abb

abbb

ac

########################

[root@09:54:05 /opt/shell05 55]#grep 't[ea]ste\{0,1\}' regular_express.txt

I can't finish the test.

Oh! The soup taste good.

[root@09:54:17 /opt/shell

[root@09:54:44 /opt/shell05 58]#grep t[ea]ste* regular_express.txt //这个如果有 多个e那么会造成误判

扩展正则:简化基本正则

\{2.3\} ==> {n,m}

(|) 或者

添加新的符号

######################################################################################

?

+

teate? 可能有也可能没有,e可以为0

[root@19:24:45 /opt/shell05 514]#egrep 't[ea]ste?' regular_express.txt

I can't finish the test.

Oh! The soup taste good.

[root@19:24:49 /opt/shell05 515]#egrep 't[ea]ste+' regular_express.txt

Oh! The soup taste good.

teaste+ 最少匹配一次 至少一次e不能没有

#############################################################################

\b 代表单词边界

#egrep 搜索不要以the开头的

[root@19:19:15 /opt/shell05 500]#egrep '\b the\b' a.txt

hello the world

filesystem the

##############################################################################

基本正则:兼容性强支持的软件多,麻烦

扩展:简单,兼容性差

egrep "(test|taste)" regular_express.txt

I can't finish the test.

Oh! The soup taste good.

##############################################

sed 命令语法格式

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~诸行处理~~~~~~~~~~~~~~

##################################################################################################

sed 【选项】 条件指令文件

sed 'd' 文件 清空文件

sed '3d' 文件 删除文件第三行

sed '1p' /etc/hosts 默认的情况下,sed /etc/passwd 不加p,会打印一遍文件,如果加上1p那么会再打一遍第一行,所以会出现两个第一行如下例子

sed  '/^#/d' regular_express.txt //可以用^#这个直接搜索到一个字符串开始来删除!!!

[root@11:45:32 /opt/shell05 156]#sed '1p' /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

172.25.0.11  server0  server server0.example.com  webapp0.example.com  www0.example.com

172.25.0.10  desktop0  desktop  desktop0.example.com  smtp0.example.com

172.25.254.254  classroom  content  classroom.example.com  content.example.com

172.25.254.250  foundation0 foundation0.example.com rhgls.domain254.example.com

[root@11:45:38 /opt/shell05 157]#

################################################################################################################################################

准确的去查找配置文件中信息:

http.conf

sed -n '/正则/p' 文件

sed -n '/html/p' 文件

[root@11:49:47 /opt/shell05 158]#sed -n '/html/p' /etc/httpd/conf/httpd.conf

# <URL:http://httpd.apache.org/docs/2.4/mod/directives.html>

DocumentRoot "/var/www/html"

<Directory "/var/www/html">

    # http://httpd.apache.org/docs/2.4/mod/core.html#options

    DirectoryIndex index.html

    # To parse .shtml files for server-side includes (SSI):

    AddType text/html .shtml

    AddOutputFilter INCLUDES .shtml

#ErrorDocument 404 /missing.html

#ErrorDocument 402 http://www.example.com/subscription_info.html

#################################################################################################################################################

sed -i 直接修改文件

sed 不加i 再屏幕上显示修改的文件

sed 修改 默认都不改源文件

sed -i '3d;2d;1d'

sed -d

sed -p

sed s/替换/g

sed s/old/new/ 单个替换,每行替换第一个,每行只替换一个

sed s/old/new/3 替换每行第几个个

sed s/old//g 替换所有

扩展替换第一个字符*** -r ***变成扩展

[root@20:15:50 /opt/shell05 724]#sed -r 's#^(.)(.*)(.)$#3\2\1#g' aa.txt

3ello the worlh

3i hao mn

[root@20:16:07 /opt/shell05 725]#sed -r 's#^(.)(.*)(.)$#\3\2\1#g' aa.txt

dello the worlh

ai hao mn

[root@20:16:14 /opt/shell05 726]#

把第二个字符和最后第二个字符对换

sed -r 's#^(.)(.)(.*)(.)(.$)#14325#g'

dello the worlh

ai hao mn

[root@15:56:36 /opt/shell05 379]#

############################

sed '/bash$/d' passwd

替换为空,删除文章内某个字符或者word

[root@14:31:00 /opt/shell05 317]#sed 's/2000//g' b.txt

 2120 2022

2111 2223

2255 2256 2277

2219 2500

  

2220  

2.

sed 's/\/bin\/bash/\sbin\/NB/g' /etc/passwd

3.sed 替换指令中的替换符号‘/’,可以改为任意其他字符,可以为#可以为!也可以为其他任何!

sed  's#/bin/bash#/sbin/NB#g' b.txt

sed  's#/bin/bash#/sbin/NB#g' passwd

sed 's/\/bin/\/bash/\/sbin\/Nologin/'

sed 'sa\abc\a\aa\a\acc\aa' 文件 替换主要是查看没有被转义字符转义的

        1           1           1

########################################################################################################################

sed -n '4,+10p' passwd 打印第四行和第四行后面的10

sed -n '/^bin/p' bin开头的行打印

sed -n 'p;n'   奇数行

sed -n    'n;p' 偶数行

#########################################################################################################################

sed '3,5d' a.txt

sed '/xml/d' a.txt

sed '/xml/d'

sed -n '$=' /etc/passwd

cat /etc/passwd | wc -l

#################################################################

-r sed 'r /etc/hosts a.txt  

 w sed  'w xx.txt'  a.txt

sed '2w xxl.txt' a.txt

[root@svr7 ~]# sed -r 's#=.*\(.*)#=172.16.0.\1#g' /etc/sysconfig/network-scripts/ifcfg-eth0

sed-e 表达式 #1,字符 25:不匹配的 ) \)

问题:

~~~~~~~~~~~~~~~~~~~~[root@11:30:04 /opt/shell05 144]#ifconfig | egrep 'inet \b' | egrep [0-9]

        inet 172.40.55.206  netmask 255.255.255.0  broadcast 172.40.55.255

        inet 127.0.0.1  netmask 255.0.0.0

        inet 192.168.4.254  netmask 255.255.255.0  broadcast 192.168.4.255

        inet 192.168.2.254  netmask 255.255.255.0  broadcast 192.168.2.255

        inet 201.1.1.254  netmask 255.255.255.0  broadcast 201.1.1.255

        inet 201.1.2.254  netmask 255.255.255.0  broadcast 201.1.2.255

        inet 172.25.254.250  netmask 255.255.255.0  broadcast 172.25.254.255

        inet 172.25.0.250  netmask 255.255.0.0  broadcast 172.25.255.255

        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Top 

NSD SHELL DAY05

案例1sed基本用法 

案例2:使用sed修改系统配置 

案例3sed多行文本处理 

案例4sed综合脚本应用 

1 案例1:sed基本用法

1.1 问题

本案例要求熟悉sed命令的p、d、s等常见操作,并结合正则表达式,完成以下任务:

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

将文件中每行的第一个、第二个字符互换

删除文件中所有的数字、行首的空格

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

1.2 方案

sed文本处理工具的用法:

用法1:前置命令 | sed  [选项]  '编辑指令'

用法2sed  [选项]  '编辑指令'  文件.. ..

相关说明如下:

编辑指令可以为增删改查等指令

定址符用来定义需要操作的文本,由“[地址1 [,地址2]]组成

未指定定址符时,默认处理所有文本

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:认识sed工具的基本选项

1)sed命令的 -n 选项

执行p打印等过滤操作时,希望看到的是符合条件的文本。但不使用任何选项时,默认会将原始文本一并输出,从而干扰过滤效果。比如,尝试用sed输出/etc/rc.local的第1行:

[root@svr5 ~]# sed '1p' /etc/rc.local

#!/bin/sh

#!/bin/sh

#

#

# This script will be executed *after* all the other init scripts.

# You can put your own initialization stuff in here if you don't

# want to do the full Sys V style init stuff.

可以发现所有的行都被显示出来了。—— 正确的用法应该添加 -n 选项,这样就可以只显示第1行了:

[root@svr5 ~]# sed -n '1p' /etc/rc.local

#!/bin/s

而在执行d删除等过滤操作时,希望看到的是删除符合条件的文本之后还能够被保留下来的文本,所以这时候就不应该使用 -n 选项了。比如,删除/etc/rc.local文件的第1-4行文本:

[root@svr5 ~]# sed '1,4d' /etc/rc.local

# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

2)sed命令的 -i 选项

正常情况下,sed命令所做的处理只是把操作结果(包括打印、删除等)输出到当前终端屏幕,而并不会对原始文件做任何更改:

[root@svr5 ~]# sed '1,4d' rclocal.txt              //删除第1~4行,输出结果

# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

[root@svr5 ~]# cat rclocal.txt                  //查看原始文本,并未改动

若希望直接修改文件内容,应添加选项 -i 。

比如,直接删除rcloal.txt文件的第1~4行,不输出结果:

[root@svr5 ~]# sed -i '1,4d' rclocal.txt            //删除操作

[root@svr5 ~]# cat rclocal.txt                      //确认删除结果

下文中关于使用sed修改文件的示例中,为了避免大家在练习过程中因误操作导致系统故障,部分命令省略 –i 选项,不再逐一说明。需要时,大家可自行加上此选项。

3)多个指令可以使用分号隔离

用分号来隔离多个操作(如果有定址条件,则应该使用{ }括起来),比如:

[root@svr5 ~]# sed -n '1p;4p' /etc/rc.local

#!/bin/sh

# You can put your own initialization stuff in here if you don't

或者:

[root@svr5 ~]# sed -n '{1p;4p}' /etc/rc.local

#!/bin/sh

# You can put your own initialization stuff in here if you don't

步骤二:认识sed工具的p输出操作

先创建一个练习用的测试文件,每一行之前添加行号,方便练习时查看效果:

[root@svr5 ~]# cat -n /etc/rc.local > rclocal.txt

[root@svr5 ~]# cat rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script will be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

1)输出所有行,相当于cat命令。

[root@svr5 ~]# sed -n 'p' rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script will be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

2)输出第4行。

[root@svr5 ~]# sed -n '4p' rclocal.txt

     4  # You can put your own initialization stuff in here if you don't

3)输出第4~7行。

[root@svr5 ~]# sed -n '4,7p' rclocal.txt

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

4)输出第4行和第7行。

[root@svr5 ~]# sed -n '4p;7p' rclocal.txt

     4  # You can put your own initialization stuff in here if you don't

     7  touch /var/lock/subsys/local

5)输出第2行及之后的3行。

[root@svr5 ~]# sed -n '2,+3p' rclocal.txt

     2  #

     3  # This script will be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

6)输出以local结尾的行。

[root@svr5 ~]# sed -n '/local$/p' rclocal.txt

     7  touch /var/lock/subsys/local

7)输出奇数行。

[root@svr5 ~]# sed -n 'p;n' rclocal.txt

     1  #!/bin/sh

     3  # This script will be executed *after* all the other init scripts.

     5  # want to do the full Sys V style init stuff.

     7  touch /var/lock/subsys/local

8)输出偶数行。

[root@svr5 ~]# sed -n 'n;p' rclocal.txt

     2  #

     4  # You can put your own initialization stuff in here if you don't

     6

9)从第5行输出到最后一行。

[root@svr5 ~]# sed -n '5,$p' rclocal.txt

     5  # want to do the full Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

10)输出文本的行数。

[root@svr5 ~]# sed -n '$=' rclocal.txt

7

步骤三:认识sed工具的d输出操作

还以rclocal.txt文件为例,文件内容如下所示:

[root@svr5 ~]# cat rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script will be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

1)删除第3~5行文本

[root@svr5 ~]# sed '3,5d' rclocal.txt

     1  #!/bin/sh

     2  #

     6

     7  touch /var/lock/subsys/local

2)删除所有包含“init”的行

[root@svr5 ~]# sed '/init/d' rclocal.txt

     1  #!/bin/sh

     2  #

     6

     7  touch /var/lock/subsys/local

3)删除所有包含“init”的行、所有包含“bin”的行

[root@svr5 ~]# sed '/init/d;/bin/d' rclocal.txt

     2  #

     6

     7  touch /var/lock/subsys/local

4)删除不包括“init”的行

[root@svr5 ~]# sed '/init/!d' rclocal.txt

     3  # This script will be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

这个实际效果相当于只显示包含“init”的行:

[root@svr5 ~]# sed -n '/init/p' rclocal.txt

     3  # This script will be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

5)删除文件的最后一行

[root@svr5 ~]# sed '$d' rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script will be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

     6

6)删除文件中的空行

手动新建一个测试文件:

[root@svr5 ~]# vim blankline.txt

abc

def

hijklmn

hello world

I am here

end

删除所有空行:

[root@svr5 ~]# sed '/^$/d' blankline.txt

abc

def

hijklmn

hello world

I am here

end

步骤四:认识sed工具的s替换操作

还以rclocal.txt文件为例,文件内容如下所示:

[root@svr5 ~]# cat rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script will be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

1)将所有行中的第一个“ll”(如果有的话)替换为“TARENA”。

[root@svr5 ~]# sed 's/ll/TARENA/' rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script wiTARENA be executed *after* all the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the fuTARENA Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

2)将所有的“ll”(如果有的话)替换为“TARENA”。

 [root@svr5 ~]# sed 's/ll/TARENA/g' rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script wiTARENA be executed *after* aTARENA the other init scripts.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the fuTARENA Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

3)将第3行内的第2个“script”替换为“SCRIPT”。

[root@svr5 ~]# sed '3s/script/SCRIPT/2' rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script will be executed *after* all the other init SCRIPTs.

     4  # You can put your own initialization stuff in here if you don't

     5  # want to do the full Sys V style init stuff.

     6

     7  touch /var/lock/subsys/local

4)删除文件内指定的字符串(替换为空)。

删除所有的“init”字符串:

[root@svr5 ~]# sed 's/init//g' rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This script will be executed *after* all the other  scripts.

     4  # You can put your own ialization stuff in here if you don't

     5  # want to do the full Sys V style  stuff.

     6

     7  touch /var/lock/subsys/local

删除所有的“script”、所有的“stuff”、所有的字母e,或者的关系用转义方式 \| 来表示:

[root@svr5 ~]# sed 's/script\|stuff\|e//g' rclocal.txt

     1  #!/bin/sh

     2  #

     3  # This  will b xcutd *aftr* all th othr init s.

     4  # You can put your own initialization  in hr if you don't

     5  # want to do th full Sys V styl init .

     6

     7  touch /var/lock/subsys/local

5)配置行的注释、解除注释。

以真实文件/etc/rc.local为例,文件内容如下:

[root@svr5 ~]# cat /etc/rc.local

#!/bin/sh

#

# This script will be executed *after* all the other init scripts.

# You can put your own initialization stuff in here if you don't

# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

解除/etc/rc.local文件第3~5行的注释(去掉开头的 # ):

[root@svr5 ~]# sed '3,5s/^#//' /etc/rc.local

#!/bin/sh

#

 This script will be executed *after* all the other init scripts.

 You can put your own initialization stuff in here if you don't

 want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

/etc/rc.local文件的第6~7行注释掉(行首添加 # ):

[root@svr5 ~]# sed '6,7s/^/#/' /etc/rc.local

#!/bin/sh

#

# This script will be executed *after* all the other init scripts.

# You can put your own initialization stuff in here if you don't

# want to do the full Sys V style init stuff.

#

#touch /var/lock/subsys/local

步骤五:利用sed完成本例要求的任务

参考数据文件内容如下:

[root@svr5 ~]# cat nssw.txt

An example Name Service Switch config file. This file should be

sorted with the most-used services at the beginning.

#

The entry '[NOTFOUND=return]' means that the search for an

entry should stop if the search in the previous entry turned

up nothing. Note that if the search failed due to some other reason

(like no NIS server responding) then the search continues with the

本小节的操作使用nssw.txt作为测试文件。

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

分两次替换操作,第一次替换掉第2个字符,第二次替换掉最后一个字符:

[root@svr5 ~]# sed 's/.//2;s/.$//' nssw.txt

A example Name Service Switch config file. This file should b

srted with the most-used services at the beginning

#

Te entry '[NOTFOUND=return]' means that the search for a

etry should stop if the search in the previous entry turne

u nothing. Note that if the search failed due to some other reaso

(ike no NIS server responding) then the search continues with th

2)将文件中每行的第一个、第二个字符互换

每行文本拆分为“第1个字符”、“第2个字符”、“剩下的所有字符”三个部分,然后通过替换操作重排顺序为“2-1-3”:

[root@svr5 ~]# sed -r 's/^(.)(.)(.*)/\2\1\3/' nssw.txt

nA example Name Service Switch config file. This file should be

osrted with the most-used services at the beginning.

#

hTe entry '[NOTFOUND=return]' means that the search for an

netry should stop if the search in the previous entry turned

pu nothing. Note that if the search failed due to some other reason

l(ike n up . Note that if the search failed due to some other

(like  NIS server responding) then the search continues with

3)删除文件中所有的数字、行首的空格

因原文件内没有数字,行首也没有空格,这里稍作做一点处理,生成一个新测试文件:

[root@svr5 ~]# sed 's/o/o7/;s/l/l4/;3,5s/^/  /' nssw.txt > nssw2.txt

[root@svr5 ~]# cat nssw2.txt

An exampl4e Name Service Switch co7nfig file. This file should be

so7rted with the most-used services at the beginning.

  #

  The entry '[NOTFOUND=return]' means that the search fo7r an

  entry sho7ul4d stop if the search in the previous entry turned

up no7thing. Note that if the search fail4ed due to some other reason

(l4ike no7 NIS server responding) then the search continues with the

nssw2.txt文件为例,删除所有数字、行首空格的操作如下:

[root@svr5 ~]# sed -r 's/[0-9]//g;s/^( )+//' nssw2.txt

4)为文件中每个大写字母添加括号

使用“&”可调用s替换操作中的整个查找串,所以可参考下列操作解决:

[root@svr5 ~]# sed 's/[A-Z]/(&)/g' nssw.txt

(A)n example (N)ame (S)ervice (S)witch config file. (T)his file should be

sorted with the most-used services at the beginning.

#

(T)he entry '[(N)(O)(T)(F)(O)(U)(N)(D)=return]' means that the search for an

entry should stop if the search in the previous entry turned

up nothing. (N)ote that if the search failed due to some other reason

(like no (N)(I)(S) server responding) then the search continues with the

2 案例2:使用sed修改系统配置

2.1 问题

本案例要求熟悉课上的sed应用案例,并编写脚本anonftp.sh,实现以下功能:

通过yum安装vsftpd软件包

修改vsftpd服务配置,开启匿名上传

调整/var/ftp/pub目录权限,允许ftp写入

启动vsftpd服务,并设置开机自运行

2.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:认识课堂上的sed练习

1)修改默认运行级别

将默认运行级别修改为5,确认修改结果:

[root@svr5 ~]# sed -i '/^id:/s/3/5/' /etc/inittab

[root@svr5 ~]# grep "^id:" /etc/inittab

id:5:initdefault:

再改回去:

[root@svr5 ~]# sed -i '/^id:/s/5/3/' /etc/inittab

[root@svr5 ~]# grep "^id:" /etc/inittab

id:3:initdefault:

2)修改IP地址的网段部分,主机地址不变。

直接修改网卡eth0的配置文件,检查原有的配置内容:

[root@svr5 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0

BOOTPROTO=none

HWADDR=00:0c:29:82:09:e9

ONBOOT=yes

NETMASK=255.255.255.0

IPADDR=192.168.4.4

TYPE=Ethernet

若希望将IP地址192.168.4.4修改为172.16.16.4,则应该定位到“IPADDR”所在的行,执行相应的替换(仅测试,尚未修改):

[root@svr5 ~]# sed '/^IPADDR/s/192.168.4.4/172.16.16.4/' \

  /etc/sysconfig/network-scripts/ifcfg-eth0 | grep "^IPADDR"

IPADDR=172.16.16.4

要求只修改网段地址时,可以利用扩展正则表达式的 \1、\2、……等调用,分别对应此前第1个、第2个、…… 以 ()包围的表达式所匹配的内容。

所以上述操作可以改为如下(启用扩展匹配应添加 -r 选项):

[root@svr5 ~]# sed -r -i '/^IPADDR/s/192.168.4.(.*)/172.16.16.\1/' \

/etc/sysconfig/network-scripts/ifcfg-eth0

确认修改结果:

[root@svr5 ~]# grep "^IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0

IPADDR=172.16.16.4

再改回去:

[root@svr5 ~]# sed -r -i '/^IPADDR/s/172.16.16.(.*)/192.168.4.\1/' \

/etc/sysconfig/network-scripts/ifcfg-eth0

[root@svr5 ~]# grep "^IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0

IPADDR=192.168.4.4

3)调整httpd服务配置,更改网站根目录

由于需要替换的字符串中有 / ,为了避免与sed替换操作的分隔混淆,可以使用其他字符作为替换分隔,比如可改用“s#old#new#”的方式实现替换:

[root@svr5 ~]# sed -i 's#/var/www/html#/opt/wwwroot#' \

/etc/httpd/conf/httpd.conf

[root@svr5 ~]# grep "^DocumentRoot" /etc/httpd/conf/httpd.conf

DocumentRoot "/opt/wwwroot"

若要恢复,可再改回去:

[root@svr5 ~]# sed -i 's#/opt/wwwroot#/var/www/html#'\

 /etc/httpd/conf/httpd.conf

[root@svr5 ~]# grep "^DocumentRoot" /etc/httpd/conf/httpd.conf

DocumentRoot "/var/www/html"

步骤二:编写anonftp.sh脚本,用来装配匿名FTP服务

1)任务需求及思路分析

vsftpd服务的安装、改目录权限、起服务等操作可以直接写在脚本中。

修改vsftpd.conf配置的工作可以使用sed命令,根据默认配置,只需要定位到以#anon开头的行,去掉开头的注释即可。

2)根据实现思路编写脚本文件

[root@svr5 ~]# vim anonftp.sh

#!/bin/bash

yum -y install vsftpd                             //安装vsftpd软件

cp /etc/vsftpd/vsftpd.conf{,.bak}                  //备份默认的配置文件

sed -i "/^#anon/s/^#//" /etc/vsftpd/vsftpd.conf      //修改服务配置

chown ftp /var/ftp/pub                              //调整目录权限

/etc/init.d/vsftpd restart                          //启动服务

chkconfig vsftpd on                                  //设为自动运行

[root@svr5 ~]# chmod +x anonftp.sh

3)验证、测试脚本

运行脚本anonftp.sh:

[root@svr5 ~]# ./anonftp.sh

.. ..

Installed:

  vsftpd.x86_64 0:2.0.5-28.el5

Complete!

关闭 vsftpd:                                              [失败]

vsftpd 启动 vsftpd:                                    [确定]

使用ftp登录服务,测试是否可以上传:

[root@svr5 ~]# ftp localhost                          //本机访问测试

Connected to localhost.localdomain.

220 (vsFTPd 2.0.5)

530 Please login with USER and PASS.

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type

Name (localhost:root): ftp                          //匿名登录

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> cd pub                                          //切换到 pub/ 目录

250 Directory successfully changed.

ftp> put install.log                          //上传当前目录下的install.log 文件

local: install.log remote: install.log

227 Entering Passive Mode (127,0,0,1,192,127)

150 Ok to send data.

226 File receive OK.

33139 bytes sent in 0.0065 seconds (5e+03 Kbytes/s)

ftp> quit                                          //断开FTP连接

221 Goodbye.

查看/var/ftp/pub新上传的文件:

[root@svr5 ~]# ls -lh /var/ftp/pub/

总计 36K

-rw------- 1 ftp ftp 33K 12-13 18:25 install.log

3 案例3:sed多行文本处理

3.1 问题

本案例要求使用sed工具来完成下列任务操作:

修改主机名配置文件

修改hosts文件,添加两条映射记录:192.168.4.5 svr5.tarena.comsvr5,还有119.75.217.56www.baidu.com

3.2 方案

sed工具的多行文本处理操作:

i:在指定的行之前插入文本

a:在指定的行之后追加文本

c:替换指定的行

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:修改主机名配置文件

1)确认修改前的配置

[root@svr5 ~]# cat /etc/sysconfig/network

NETWORKING=yes

HOSTNAME=svr5.tarena.com

2)使用sed修改主机名配置所在行的内容(c整行替换)

[root@svr5 ~]# sed  '/^HOSTNAME/cHOSTNAME=mysvr.tarena.com' /etc/sysconfig/network

步骤二:修改hosts文件,添加新的记录

1)确认修改前的配置

[root@svr5 ~]# cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

2)使用sed修改hosts文件,添加两行新纪录(a追加)

[root@svr5 ~]# sed  -i  '$a192.168.4.5  svr5.tarena.com svr5\

> 119.75.217.56  www.baidu.com' /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.4.5  svr5.tarena.com svr5

119.75.217.56  www.baidu.com

4 案例4:sed综合脚本应用

4.1 问题

本案例要求编写脚本getupwd.sh,实现以下需求:

找到使用bash作登录Shell的本地用户

列出这些用户的shadow密码记录

按每行用户名 --> 密码记录保存到getupwd.log,如图-1所示

图-1

4.2 方案

基本思路如下:

先用sed工具取出登录Shell/bin/bash的用户记录,保存为临时文件/tmp/urec.tmp,并计算记录数量

再结合while循环遍历取得的账号记录,逐行进行处理

针对每一行用户记录,采用掐头去尾的方式获得用户名、密码字串

按照指定格式追加到/tmp/getuupwd.log文件

结束循环后删除临时文件,报告分析结果

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写getupwd.sh脚本

[root@svr5 ~]# vim ./getupwd.sh  

#/bin/bash

> /tmp/getupwd.log                                     ## 创建空文件

sed -n '/:\/bin\/bash$/w /tmp/urec.tmp' /etc/passwd      ## 提取符合条件的账号记录

UNUM=$(egrep -c '.' /tmp/urec.tmp)                   ## 取得记录个数

while [ ${i:=1} -le $UNUM ]                         ## 从第1行开始,遍历账号记录

do

    UREC=$(sed -n "${i}p" /tmp/urec.tmp)              ## 取指定行数的记录

    NAME=${UREC%%:*}                                 ## 截取用户名(记录去尾)

    PREC=$(sed -n "/^$NAME:/p" /etc/shadow)          ## 查找与用户名对应的密码记录

    PASS=${PREC#*:}                                  ## 掐头

    PASS=${PASS%%:*}                                ## 去尾,只留下密码记录

    echo "$NAME --> $PASS" >> /tmp/getupwd.log         ## 保存结果

    let i++                                           ## 自增1,转下一次循环

done

/bin/rm -rf /tmp/urec.tmp                           ## 删除临时文件

echo "用户分析完毕,请查阅文件 /tmp/getupwd.log"         ## 完成后提示

[root@svr5 ~]# chmod +x ./getupwd.sh

步骤二:测试、验证执行结果

[root@svr5 ~]# ./getupwd.sh     

用户分析完毕,请查阅文件 /tmp/getupwd.log

[root@svr5 ~]# less /tmp/getupwd.log

root --> $6$IWgMYmRACwdbfwBo$dr8Yn983nswiJVw0dTMjzbDvSLeCd1GMYjbvsDiFEkL8jnXOLcocBQypOCr4C6BRxNowIxjh6U2qeFU0u1LST/

zengye --> $6$Qb37LOdzRl5995PI$L0zTOgnhGz8ihWkW81J.5XhPp/l7x2./Me2ag0S8tRndCBL9nIjHIKkUKulHxJ6TXyHYmffbVgUT6pbSwf8O71

clamav --> !!

mysql --> !!

abc --> !!

.. ..

从上述参考脚本可以发现,使用sed来实现字段提取会比较复杂。下一章课程将会学到awk命令,届时可以通过更简单的方法来改进此脚本内容。

猜你喜欢

转载自www.cnblogs.com/fuzhongfaya/p/8952513.html