sed命令是用來處理文本的,且是按行來處理文本,sed處理文本時會將文本內容放置在模式空間中,處理完之後輸出模式空間中的文本內容,所以如果你用sed命令處理一個文件,是不會改變文件內容本身的,改變的只是模式空間的臨時內容。
sed 'AddressCommand' file ...
Address:可以理解為定位數據,通過一系列的操作,篩選出需要的數據
Command:對選出的數據(行)進行一些什麼樣的操作
下面分開來說
Address:
1、StartLine,EndLine
例:
1,100 --就是1到100行的意思
$: --最後一行
2、/RegExp/
通過正則表達式來匹配
例:
/^pas/ --以pas開頭的行
3、/pattern1/,/pattern2/
第一次被pattern1匹配到行開始,至第一次被pattern2匹配到的行結束,這中間的所有行
4、LineNumber
指定的行
5、StartLine, +N
從startLine開始,向後的N行
Command:
d:刪除符合條件的行
p:顯示符合條件的行
a \string:在指定的行後面追加新行,內容為string
i \string:在指定的行前面追加新行,內容為string
r FILE: 將指定的文件的內容添加至符合條件的行處
w FILE: 將地址指定的范圍內的行另存至指定的文件中;
s/pattern/string/修飾符:查找並替換,默認只替換每行中第一次被模式匹配到的字符串
加修飾符
g: 全局替換
i: 查找時忽略字符大小寫
s///: s###, s@@@ --使用s時,不僅可以用/來做分隔符,還可以使用#和@
\(\), \1, \2 --支持後向引用
&: 引用模式匹配到的整個字符串
例:以/etc/fstab文件為例
#
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# 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=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
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
刪除前10行
[root@iZ28g26851kZ ~]# sed '1,10d' /etc/fstab
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@iZ28g26851kZ ~]#
刪除#號開頭的行
[root@iZ28g26851kZ ~]# sed '/^#/d' /etc/fstab
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
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
[root@iZ28g26851kZ ~]#
例:顯示以#號開頭的行
[root@iZ28g26851kZ ~]# sed '/^#/p' /etc/fstab
#
#
# /etc/fstab
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# 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
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
#
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
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
[root@iZ28g26851kZ ~]#
居然顯示了2遍,不但如此,沒有被匹配到的行也顯示出來了,
為什麼呢?
之前有提到過,sed處理文本是先讀到模式空間中,處理完在顯示出來,之前的刪除,sed將模式空間中符合匹配結果的行刪除掉,然後將模式空間中剩下的行顯示出來這沒有問題,但是現在,sed是將匹配到的結果顯示出來了,但是同時還要將模式空間中的內容也顯示出來,所以就出現了這樣的尴尬局面~~
怎麼解決呢?
-n
使用-n命令可以開啟靜默模式,也就是不會再將模式空間中的內容顯示出來,而是只顯示匹配到的結果
[root@iZ28g26851kZ ~]# sed -n '/^#/p' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# 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
#
[root@iZ28g26851kZ ~]#
例:在所有的#號所在行之下再添加一行 “test”
[root@iZ28g26851kZ ~]# sed '/^#/a \test' /etc/fstab
#
test
# /etc/fstab
test
# Created by anaconda on Mon Aug 11 16:27:41 2014
test
#
test
# Accessible filesystems, by reference, are maintained under '/dev/disk'
test
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
test
#
test
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
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
[root@iZ28g26851kZ ~]#
例:將#號開頭的行保存到test10.txt文件中
[root@iZ28g26851kZ ~]# sed '/^#/w test10.txt' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# 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=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 / ext4 defaults,barrier=0 1 1
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
[root@iZ28g26851kZ ~]# ls
exittest.sh libiconv-1.14 mhash-0.9.4.tar.gz mysql-5.1.51.tar.gz nginx-1.8.0.tar.gz test10.txt
filetest.sh libiconv-1.14.tar.gz mysql-5.1.51 nginx-1.8.0 shifttest.sh vartest.sh
[root@iZ28g26851kZ ~]# cat test10.txt
#
# /etc/fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# 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
#
[root@iZ28g26851kZ ~]#
例:將所有的 / 替換成 “@O@”
[root@iZ28g26851kZ ~]# sed 's#/#@O@#g' /etc/fstab
#
# @O@etc@O@fstab
# Created by anaconda on Mon Aug 11 16:27:41 2014
#
# Accessible filesystems, by reference, are maintained under '@O@dev@O@disk'
# See man pages fstab(5), findfs(8), mount(8) and@O@or blkid(8) for more info
#
UUID=e76a7b8d-20c2-4f94-bdd1-f4054a34c206 @O@ ext4 defaults,barrier=0 1 1
tmpfs @O@dev@O@shm tmpfs defaults 0 0
devpts @O@dev@O@pts devpts gid=5,mode=620 0 0
sysfs @O@sys sysfs defaults 0 0
proc @O@proc proc defaults 0 0
[root@iZ28g26851kZ ~]#
-i
之前說過sed所有的操作都是針對模式空間進行的,並不會影響到源文件,
那如果確實像將源文件修改掉呢?
那就使用-i選項
這樣就直接操作的是源文件了,所以慎用~~
-e
同時執行多個腳本
sed -e 'AddressComment' -e 'AddressComment' file ...
-f
將腳本寫到一個文件中,每一行為一個腳本,然後,,,
sed -f /xxx/xxx.xx file ...
-r
支持擴展正則表達式