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命令,屆時可以通過更簡單的方法來改進此腳本內容。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM