第一部分、Linux文本處理三劍客之sed(Stream EDitor)文本編輯工具
一、sed的基本功能工作原理
sed是一種流編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接著用sed命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。接著處理下一行,這樣不斷重復,直到文件末尾。文件內容并沒有改變,除非你使用重定向存儲輸出。sed默認只要被模式匹配到不管有沒有編輯(edit)都會有標準輸出(stdout),因此我們常用-n選項搭配使用。 Sed主要用來自動編輯一個或多個文件,簡化對文件的反復操作,編寫轉換程序等。
二、sed命令的常用選項
sed [OPTION]… 'scripts' [input-file]…
scripts:地址定界編輯命令
常用選項:
-n:不輸出模式空間中的內容至屏幕
-e:支持多條命令執行,意味多點編輯
-f /PATH/TO/SCRIPT_FILE: 從指定文件中讀取編輯腳本(每行一個編輯命令)
-r: 支持使用擴展正則表達式
-i: 直接編輯原文件(不建議使用,一旦修改,刪了就找不回來了,通常使用-i.bak來備份)
三、sed命令的地址定界
(1) 不給地址:(空地址)對全文進行處理
(2) 單地址:
#: 指定的行
/pattern/:被此處模式所能夠匹配到的每一行
(3) 地址范圍:
#,# 從第#行到第#行中間的行
#,+# 從第#行到第#+#行中間的行
/pat1/,/pat2/ 從模式part1匹配到的行開始到被模式part2匹配到行的中間行
#,/pat1/ 從第#行開始到被模式part1匹配到中間的行
(4) ~:步進
1~2 奇數行
2~2 偶數行
四、sed常用的編輯命令
d命令: 刪除模式空間匹配的行
舉例子:
1、sed '1,5d' /etc/fstab 刪除/etc/fstab文件的第1行到第5行
2、sed '3d' /etc/fstab 刪除/etc/fstab文件的第3行
3、sed '/^#/d' /etc/fstab 刪除/etc/fstab文件#開頭的行
4、sed '1~2d' /etc/fstab 刪除/etc/fstab文件的中的奇數行顯示偶數行
p命令: 顯示模式空間中的內容(顯示模式匹配到的行)
舉例子:
1、sed '1~2p’ /etc/fstab 會顯示兩次奇數行(默認匹配到會有一次輸出)
2、sed -n '1~2p’ /etc/fstab 禁止默認的輸出,僅顯示一次奇數行
a命令:a \text:在行后面追加文本;支持使用\n實現多行追加
i命令:i \text:在行前面插入文本;支持使用\n實現多行插入
舉例子:
1、sed '3i \new line’ /etc/fstab 在/etc/fstab文件的第三行前面插入new line字段(其 它默認輸出)
2、sed '3a \new line’ /etc/fstab 在/etc/fstab文件的第三行后面追加new line字段(其 它默認輸出)
支持文本多行顯示:
3、sed '3a \new line\n another new line’ /etc/fstab
在/etc/fstab文件的第三行后面追加new line和another new line字段的兩行
4、sed '/^UUID/a \#add new device base on UUID’ /etc/fstab
在/etc/fstab文件的以UUID開頭的行后面添加#…..后面的備注信息
c命令:c \text:把匹配到的行替換成此處指定的文本“text”整行替換
舉例子:
1、sed '/^UUID/c \#add new device base on UUID’ /etc/fstab
在/etc/fstab文件的以UUID開頭的行均被替換為#…..上面的字符
w命令:w /path/to/somefile: 保存模式空間匹配的行至指定文件
舉例子:
第一步: sed -n '/^[^#]/p ' /etc/fstab
將以非#號開頭的行顯示出來
第二步: sed '/^[^#]/w /tmp/fstab.new' /etc/fstab
將非#開頭的行寫到文件/tmp/fstab.new文件中
r命令:r /path/from/somefile:讀取指定文件的文本至模式空間中匹配到的行后
舉例子:
1、sed '3r /etc/issue' /etc/fstab
在/etc/fstab的第三行后面加入/etc/issue中文件的內容
=命令: =為模式空間中的行打印行號
舉例子:
1、sed '/^UUID/=' /etc/fstab
在/etc/fstab文件中以UUID開頭的行,另外換行加入行號
!命令: 模式空間中匹配行取反處理
舉例子:
1、sed '/^#/!d' /etc/fstab 刪除不以#開頭的行
s命令: s/// 查找替換,其分隔符可自行指定s@@@或s$$$等
替換標記:
g: 行內全局替換
p: 顯示替換成功的行
w /PATH/TO/SOMEFILE:將替換成功的行保存至文件中
五、sed命令使用示例
-
sed ‘2p’ /etc/passwd 顯示/etc/passwd文件第二行兩次
-
sed –n ‘2p’ /etc/passwd 顯示/etc/passwd文件第二行
-
sed –n ‘1,4p’ /etc/passwd 顯示/etc/passwd文件第1到4行
-
sed –n ‘/root/p’ /etc/passwd 顯示/etc/passwd文件匹配到root字符的行
-
sed –n ‘2,/root/p’ /etc/passwd 顯示該文件從2行開始到匹配到含有root字符的行中間的行
-
sed -n ‘/^$/=’ file 顯示該文件空行行號
-
sed –n –e ‘/^$/p’ –e ‘/^$/=’ file 顯示該文件空行并且打印其空行的行號
-
sed ‘/root/a\superman’ /etc/passwd 在該文件匹配到root字符行的行后(換行)加上superman字段
-
sed ‘/root/i\superman’ /etc/passwd 在該文件匹配到root字符行的行前(換行)插入superman字段
-
sed ‘/root/c\superman’ /etc/passwd 把該文件匹配到root字符行(整行)替換成superman字段的行
-
sed ‘/^$/d’ file 刪除該文件中的空白行
-
sed ‘1,10d’ file 刪除該文件中的第1到10行
-
nl /etc/passwd | sed ‘2,5d’ 刪除/etc/passwd文件中的第2到5行
-
nl /etc/passwd | sed ‘2a\tea’ 在/etc/passwd文件的第2行后(換行)追加tea字段的行
-
sed 's/test/mytest/g' example 全局將test字符串替換為mytest字符串
-
sed –n‘s/root/&superman/p’ /etc/passwd 匹配到該文件含有root的行,并在root后面添加superman
-
sed –n‘s/root/superman&/p’ /etc/passwd 匹配到該文件含有root的行,并在root前面添加superman
-
sed -e ‘s/dog/cat/’ -e ‘s/hi/lo/’pets 匹配該文件含有dog和hi的行,并將其字符替換為cat和lo
-
sed –i.bak ‘s/dog/cat/g’ pets 全局將含有dog的行中的dog字符串替換為cat,且在原文上修 改,并且生成pets.bak的備份文件(未修改的原文件)
六、sed命令相關練習
#1、刪除/etc/grub2.conf文件中所有以空白開頭的行行首的空白字符 sed -r 's@^[[:space:]]+@@' /etc/grub2.cfg [root@localhost ~]# sed -r 's@^[[:space:]]+@@' /etc/grub2.cfg # # DO NOT EDIT THIS FILE # # It is automatically generated by grub2-mkconfig using templates # from /etc/grub.d and settings from /etc/default/grub # ### BEGIN /etc/grub.d/00_header ### set pager=1 if [ -s $prefix/grubenv ]; then load_env fi if [ "${next_entry}" ] ; then set default="${next_entry}" set next_entry= save_env next_entry set boot_once=true else set default="${saved_entry}" fi if [ x"${feature_menuentry_id}" = xy ]; then menuentry_id_option="--id" else menuentry_id_option="" fi export menuentry_id_option #2、刪除/etc/fstab文件中所有以#開頭,后面至少跟一個空白字符的行的行首的#和空白字符 sed 's@^#[[:space:]]\+@@' /etc/fstab [root@localhost ~]# sed 's@^#[[:space:]]\+@@' /etc/fstab # /etc/fstab Created by anaconda on Sun Jul 24 11:42:46 2016 # Accessible filesystems, by reference, are maintained under '/dev/disk' See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # UUID=bd6898a4-e81d-484f-a98c-bf0db692a30b / xfs defaults 0 0 UUID=cfa0ba95-faf2-41ed-a849-70c59f56e00a /boot xfs defaults 0 0 UUID=b1c4ae19-2384-4e09-bea7-2f1cffaa3dcb /testdir xfs defaults 0 0 UUID=4c2a179a-61d4-4a7f-91f0-15979fc699f2 swap swap defaults 0 0 #3、在/root/install.log每一行行首增加#號 sed -r 's@(.*)@#\1@g' /root/install.log 或者sed 's@^@#@' /root/install.log [root@centos6 testdir]# sed -r 's@(.*)@#\1@g' /root/install.log #Installing ql2100-firmware-1.19.38-3.1.el6.noarch #Installing ivtv-firmware-20080701-20.2.noarch #Installing libertas-usb8388-firmware-5.110.22.p23-3.1.el6.noarch #Installing xorg-x11-drv-ati-firmware-7.6.1-2.el6.noarch #Installing ql2500-firmware-7.03.00-1.el6_5.noarch #Installing atmel-firmware-1.3-7.el6.noarch #Installing zd1211-firmware-1.4-4.el6.noarch #Installing iwl4965-firmware-228.61.2.24-2.1.el6.noarch #Installing rt61pci-firmware-1.2-7.el6.noarch #Installing iwl3945-firmware-15.32.2.9-4.el6.noarch #Installing ql2200-firmware-2.02.08-3.1.el6.noarch #Installing rt73usb-firmware-1.8-7.el6.noarch #Installing ipw2100-firmware-1.3-11.el6.noarch #Installing ql23xx-firmware-3.03.27-3.1.el6.noarch #Installing ipw2200-firmware-3.1-4.el6.noarch #Installing rootfiles-8.1-6.1.el6.noarch #Installing man-pages-3.22-20.el6.noarch #Installing words-3.0-17.el6.noarch #*** FINISHED INSTALLING PACKAGES ***[root@centos6 testdir]# #4、在/etc/fstab文件中不以#開頭的行的行首增加#號 sed 's@^[^#].*@#&@' /etc/fstab [root@centos6 testdir]# sed 's@^[^#]@#&@' /etc/fstab # # /etc/fstab # Created by anaconda on Mon Jul 25 01:30:22 2016 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # #UUID=eb1a1164-fb03-45f1-8b2d-9d046d3e228b / ext4 defaults 1 1 #UUID=439d1457-04f7-4069-b3ac-04e77c29543c /boot ext4 defaults 1 2 #UUID=b7bff15d-cd5e-4be3-ace6-22c688569b26 /testdir ext4 defaults 1 2 #UUID=3a2ca217-2ea4-48f2-8294-55495b01c3a9 swap swap defaults 0 0 #tmpfs /dev/shm tmpfs defaults 0 0 #devpts /dev/pts devpts gid=5,mode=620 0 0 #sysfs /sys sysfs defaults 0 0 #proc /proc proc defaults 0 0 #5、處理/etc/fstab路徑,使用sed命令取出其目錄名和基名 echo /etc/sysconfig/ |sed -r 's#[^/]+/?$##' 目錄名 echo "/etc/fst/sd" | sed -r 's@(.*/)([^/]+/?)$@\1@' 目錄名 echo "/etc/fstab/" | sed 's@^.*\<@@' 基名 [root@centos6 ~]# echo /etc/sysconfig/ |sed -r 's#[^/]+/?$##' /etc/ [root@centos6 ~]# echo "/etc/fst/sd" | sed -r 's@(.*/)([^/]+/?)$@\1@' /etc/fst/ [root@centos6 ~]# echo "/etc/fstab/" | sed 's@[^/]\+/\?$@@' /etc/ [root@centos6 ~]# echo "/etc/fstab/" | sed 's@^.*\<@@' fstab/ #6、利用sed 取出ifconfig命令中本機的IPv4地址 ifconfig|sed -n 2p |sed -r 's/.*addr:(.*) Bca.*/\1/' 或者ifconfig|sed -n 2p |sed -e 's/.*addr://' -e 's/ B.*//' 或者ifconfig|sed -n 2p |sed -r 's/.*addr:(.*) Bca.*/\1/' [root@centos6 ~]# ifconfig|sed -n 2p |sed -r 's/.*addr:(.*) Bca.*/\1/' 172.18.18.203 [root@centos6 ~]# ifconfig|sed -n 2p |sed -e 's/.*addr://' -e 's/ B.*//' 172.18.18.203 [root@centos6 ~]# ifconfig|sed -n 2p |sed -r 's/.*addr:(.*) Bca.*/\1/' 172.18.18.203 #7、統計centos安裝光盤中Package目錄下的所有rpm文件的以.分隔倒數第二個字段的重復次數 [root@centos6 ~]# ls /media/CentOS_6.8_Final/Packages |grep -v '.*.rpm' TRANS.TBL 由于該文件夾下面的文件有以TRANS.TBL結尾的文件,因此需要濾除 ls /media/CentOS_6.8_Final/Packages |grep -o '.*.rpm' |sed -r 's#.*\.(.*)\.rpm$#\1#'|sort |uniq -c [root@centos6 ~]# ls /media/CentOS_6.8_Final/Packages |grep -o '.*.rpm' |sed -r 's#.*\.(.*)\.rpm$#\1#'|sort |uniq -c 4 i686 919 noarch 2283 x86_64 或者ls /media/CentOS_6.8_Final/Packages |grep -o '.*.rpm' |rev |cut -d. -f2 |rev|sort |uniq -c [root@centos6 ~]# ls /media/CentOS_6.8_Final/Packages |grep -o '.*.rpm' |rev |cut -d. -f2 |rev|sort |uniq -c 4 i686 919 noarch 2283 x86_64
原創文章,作者:AndyIvanXue,如若轉載,請注明出處:http://www.www58058.com/32099