sed

sed命令:行編輯器;
默認不是直接編輯原文件,而是先把原文件複製一份,在內存中執行編譯操作.
假如有一個文件,上面有多行文本數據,sed從該文件中一次先讀出一行,它不會修改原文件的那一行,只是先複製出來,然後把這一行放在自己的工作車間內(pattern space),首先先判斷一下該行是否是其要匹配的行,如果是則先進行編輯處理(edit)經過處理以後,其結果將會被送入到標準輸出(stdout),如果不是其要匹配的行,則默認直接送到標準輸出(stdout),我們也可以隱藏,可以設置不是要匹配的行,不用標準輸出,是匹配的行,直接編輯顯示
地址定界編輯命令
 常用選項:
 -n:不輸出模式空間中的內容至屏幕;
 -e script, --expression=script:多點編輯;
 -f  /PATH/TO/SED_SCRIPT_FILE
 每行一個編輯命令;
 -r, --regexp-extended:支持使用擴展正則表達式;
 -i[SUFFIX], --in-place[=SUFFIX]:直接編輯原文件 ;
 ~]# sed  -e  's@^#[[:space:]]*@@'   -e  '/^UUID/d'  /etc/fstab  
地址定界:
 (1)(不給地址) 空地址:對全文進行處理;
 (2) 單地址:
    #:指定行;
        /pattern/:被此模式所匹配到的每一行;
 (3) 地址範圍
        #,#:比如從第1行到第1行
        #,+#:不如3,+8從第3行開始向下8行,包括第3行一共9行
         # ,/pat1/: 表示從指定的行開始一直到第一次能被模式所匹配到的行結束之間的所有行
            /pat1/,/pat2/:表示從第一次被模式所匹配到的行到第2次被模式所匹配到的行之間的所有行
    $:最後一行;
   (4) 步進:~
    1~2:所有奇數行
    2~2:所有偶數行
    
編輯命令:
      d:刪除;注意該命令是一個比較特殊的操作。該命令把整行都給刪除了,所以是無法輸出的。
[root@bogon ~]# cp /etc/fstab /tmp/lilu
cp: overwrite `/tmp/lilu'? y
[root@bogon ~]# cat /tmp/lilu


#
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 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=2327d6c1-d73d-4037-aa9b-493c9b868b0a /                       ext4    defaults        1 1
UUID=e22e484a-ae98-4559-929e-0a5515884469 /boot                   ext4    defaults        1 2
UUID=f5c34482-509d-44e5-a76c-5ad25f549de2 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
LABEL=MYDATA            /mydata                 ext2    defaults,acl    0
[root@bogon ~]# sed '1,5d' /tmp/lilu
# 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=2327d6c1-d73d-4037-aa9b-493c9b868b0a /                       ext4    defaults        1 1
UUID=e22e484a-ae98-4559-929e-0a5515884469 /boot                   ext4    defaults        1 2
UUID=f5c34482-509d-44e5-a76c-5ad25f549de2 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
LABEL=MYDATA            /mydata                 ext2    defaults,acl    0    
由上可見:第1行至第5行完全被刪除,所以前五行沒有數據輸出,所輸出的全是第6行開始以後的行。
加入-n選項後:則禁止,默認沒有模式匹配到時則直接輸出的行爲
[root@bogon ~]# sed  -n '1,5d' /tmp/lilu
[root@bogon ~]#
因爲這次模式匹配到後面跟的是刪除,所以就什麼也沒有輸出,如果後面跟的是替換則將替換後的值輸出:


[root@bogon ~]# sed '1~2d' /etc/fstab
#
# Created by anaconda on Sun May  8 14:27:02 2016
# Accessible filesystems, by reference, are maintained under '/dev/disk'
#
UUID=e22e484a-ae98-4559-929e-0a5515884469 /boot                   ext4    defaults        1 2
該命令的意思是顯示偶行:因爲'1~2d'的含義是刪除奇數行,所以顯示的是偶數行
p:顯示匹配到的模式空間中的內容;
[root@bogon ~]# sed '1~2p' /etc/fstab



#
# /etc/fstab
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 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
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=2327d6c1-d73d-4037-aa9b-493c9b868b0a /                       ext4    defaults        1 1
UUID=2327d6c1-d73d-4037-aa9b-493c9b868b0a /                       ext4    defaults        1 1
由此可見使用p選項後,顯示的是該奇數行,並且顯示了2次!這是因爲默認被匹配到的行顯示,然後後面跟的編輯選項是p,根據其含義所以又顯示了一遍因此一個顯示了2次!
若如果只想其顯示一次則需要跟上面的一樣,在前面加一個-n,禁止掉默認輸出!
a  \text:在行後面追加文本“text”,支持使用反斜線\n實現多行追加;
i  \text:在行前面插入文本“text”,支持使用反斜線\n實現多行插入;
[root@bogon ~]# cat /tmp/lilu


#
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 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 in
[root@bogon ~]# sed '3i \new line' /tmp/lilu


#
new line
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 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 in
使用i後可見第在第3行插入了new line 原來的第3行變爲了第4行。
使用a後如下:
[root@bogon ~]# sed '1a \new line' /tmp/lilu


new line
#
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 2016
也可以使用\n來轉行進行多行輸出:
[root@bogon ~]# sed '1a \new line\n哈哈 哦哈哈哈' /tmp/lilu


new line
哈哈 哦哈哈哈
#
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 2016


c  \text:把匹配到的行替換爲此處指定的文本“text”;
[root@bogon ~]# sed '1c\哈哈 哦哈哈哈' /tmp/lilu
哈哈 哦哈哈哈
#
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 2016
由此可見被匹配到第第一行被替換成了哈哈 哦哈哈哈
w /PATH/TO/SOMEFILE:保存模式空間匹配到的行至指定的文件中;
練習:將/tmp/lilu 所有非#號開頭的行全部匹配到/tmp/fstab,new文件中
[root@bogon ~]# sed '/^[^#]/w /tmp/fstab.new' /tmp/lilu
#
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 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=2327d6c1-d73d-4037-aa9b-493c9b868b0a /                       ext4    defaults        1 1
UUID=e22e484a-ae98-4559-929e-0a5515884469 /boot                   ext4    defaults        1 2
UUID=f5c34482-509d-44e5-a76c-5ad25f549de2 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
LABEL=MYDATA            /mydata                 ext2    defaults,acl    0 0
[root@bogon ~]# cat /tmp/fstab.niu
cat: /tmp/fstab.niu: No such file or directory
[root@bogon ~]# cat /tmp/fstab.new
UUID=2327d6c1-d73d-4037-aa9b-493c9b868b0a /                       ext4    defaults        1 1
UUID=e22e484a-ae98-4559-929e-0a5515884469 /boot                   ext4    defaults        1 2
UUID=f5c34482-509d-44e5-a76c-5ad25f549de2 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
LABEL=MYDATA            /mydata                 ext2    defaults,acl    0 0


r  /PATH/FROM/SOMEFILE:讀取指定文件的內容至當前文件被模式匹配到的行後面;文件合併;
[root@bogon ~]# cat /etc/issue
CentOS release 6.7 (Final)
Kernel \r on an \m


[root@bogon ~]# sed '3r /tmp/lilu' /etc/issue
CentOS release 6.7 (Final)
Kernel \r on an \m



#
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 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=2327d6c1-d73d-4037-aa9b-493c9b868b0a /                       ext4    defaults        1 1


=:爲模式匹配到的行打印行號;
[root@bogon ~]# sed '/UUID/=' /tmp/lilu
#
9
UUID=2327d6c1-d73d-4037-aa9b-493c9b868b0a /                       ext4    defaults        1 1
10
UUID=e22e484a-ae98-4559-929e-0a5515884469 /boot                   ext4    defaults        1 2
11
UUID=f5c34482-509d-44e5-a76c-5ad25f549de2 swap                    swap    defa
!:條件取反;
刪除/tmp/lilu中所有以非#號開頭的行
[root@bogon ~]# sed '/^#/!d' /tmp/lilu
#
# /etc/fstab
# Created by anaconda on Sun May  8 14:27:02 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 inf
格式:地址定界!編輯命令;
s///:查找替換,其分隔符可自行指定,常用的有s@@@, s###等;
替換標記:
g:全局替換;
w /PATH/TO/SOMEFILE:將替換成功的結果保存至指定文件中;
p:顯示替換成功的行;
    
練習1:刪除/etc/grub2.cfg文件中所有以空白字符開頭的行的行首的所有空白字符;
~]# sed  's@^[[:space:]]\+@@' /etc/grub2.cfg
因爲是對全文匹配所有不需要給地址。
練習2:刪除/etc/fstab文件中所有以#開頭的行的行首的#號及#後面的所有空白字符;
~]# sed  's@^#[[:space:]]*@@'  /etc/fstab
練習3:輸出一個絕對路徑給sed命令,取出其目錄,其行爲類似於dirname;
~]# echo "/var/log/messages/" | sed 's@[^/]\+/\?$@@'
~]# echo "/var/log/messages" | sed -r 's@[^/]+/?$@@'
     
高級編輯命令:
h:把模式空間中的內容覆蓋至保持空間中;
H:把模式空間中的內容追加至保持空間中;
g:把保持空間中的內容覆蓋至模式空間中;
G:把保持空間中的內容追加至模式空間中;
x:把模式空間中的內容與保持空間中的內容互換;
n:覆蓋讀取匹配到的行的下一行至模式空間中;
N:追加讀取匹配到的行的下一行至模式空間中;
d:刪除模式空間中的行;
D:刪除多行模式空間中的所有行;
   
示例:
sed  -n  'n;p'  FILE:顯示偶數行;
sed  '1!G;h;$!d'  FILE:逆序顯示文件的內容;
sed  ’$!d'  FILE:取出最後一行;
sed  '$!N;$!D' FILE:取出文件後兩行;
sed '/^$/d;G' FILE:刪除原有的所有空白行,而後爲所有的非空白行後添加一個空白行;
sed  'n;d'  FILE:顯示奇數行;
sed 'G' FILE:在原有的每行後方添加一個空白行;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章