Sed文本文件工具的使用詳解
一、概述
sed 工具實際上就是一個非交互式的編輯器,主要是為了處理文本而生的,我們知道處理文本的三劍客是 grep sed awk 我們之前學習過 grep 文本過濾工具,它的主要作用是為了過濾文本,而sed 工具也是過濾文本,只不過sed工具針對的是文件中的每一行,而且sed工具更加強大,下面還具體說明一下sed 工具的原理。
二、sed 原理
sed 工具實際上的原理,我用一幅圖給大家闡述一下:
我這里引用一篇博客中對sed工具的定義:
sed工具全稱為流式編輯器,它可以被使用作為行過濾器(顧名思義sed是按照行查找進行操作的),它的工作原理可以描述為:把前一個程序的輸出引入到sed的輸入,經過一系列編輯命令轉換為另外一種格式輸出。(形象的解釋如下圖所示,模式空間會在后面單獨提出)
sed是一個非交互式的流編輯器(stream editor)。所謂非交互式,是指使用sed只能在命令行下輸入編輯命令來編輯文本,然后在屏幕上查看輸出;而所謂流編輯器,是指sed每次只從文件(或輸入)讀入一行,然后對該行進行指定的處理,并將結果輸出到屏幕(除非取消了屏幕輸出又沒有顯式地使用打印命令),接著讀入下一行。整個文件像流水一樣被逐行處理然后逐行輸出。
sed一次處理一行內容。處理時,把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接著用sed命令處理緩沖區(pattern space)中的內容,處理完成后,把緩沖區(pattern space)的內容送往屏幕。接著清空緩沖區(pattern space),處理下一行,這樣不斷重復,直到文件末尾。
pattern space(模式空間)相當于車間sed把流內容在這里處理;
hold space(保留空間)相當于倉庫,加工的半成品在這里臨時儲存(當然加工完的成品也在這里存儲)。
How sed Works:
先讀入一行,去掉尾部換行符,存入pattern space,執行編輯命令。
處理完畢,除非加了-n參數,把現在的pattern space打印出來,在后邊打印曾去掉的換行符。
把pattern space內容給hold space,把pattern space置空。
接著讀下一行,處理下一行。
一種非平凡情況,一個文件僅一行,尾部沒換行,sed只打印,不會尾部加換行,但若在尾部又附加了輸出,他會再補上那個換行。
下面我們邊舉例子 邊來介紹sed 命令的選項和sed 命令的用法:
三、sed 命令的選項及其用法
要想真正了解并熟練使用sed 命令,必須知道sed 命令的執行過程,sed 命令是按照模式進行匹配后輸出的,sed命令中有2個空間,一個叫做模式空間(pattern mode) 一個叫做保留空間(hold mode) 我們可以把模式空間想象成為一個流水線,把保留空間想象成為一個倉庫,
比如下面的命令
sed '2,3p' /etc/fstab
執行的過程其實是這樣,我畫一幅圖來展示一下執行的流程,我們先來看/etc/fstab 中的內容:
1
2 #
3 # /etc/fstab
4 # Created by anaconda on Tue Aug 23 16:38:07 2016
5 #
6 # Accessible filesystems, by reference, are maintained under '/dev/disk'
7 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8 #
9 /dev/mapper/centos-root / xfs defaults 0 0
10 UUID=79e2f3d9-4bd1-4b1c-beda-dcac56065789 /boot xfs defaults 0 0
11 /dev/mapper/centos-home /home xfs defaults 0 0
12 /dev/mapper/centos-swap swap swap defaults 0 0
13 /dev/sdc1 /mydata ext4 defaults 0 0
當我們執行sed 命令的時候,他是把文件中的內容一行一行讀入到模式空間中,
通過上面我這個草圖可以看出,sed 執行的時候是一行一行的把文件中的內容讀入到模式空間中,然后再分析sed命令進行匹配,最后輸出到標準輸出(顯示器)上。
下面我介紹一下sed的常用選項并通過習題練習講解sed的基本用法和高級用法,首先我們man 一下sed
sed - stream editor for filtering and transforming text
sed [OPTION]... {script-only-if-no-other-script} [input-file]..
3.1[option] 選項介紹:
1、 -n 選項 不輸出模式空間中的內容至屏幕
例如:
[root@localhost test2]# cat -n /etc/fstab
1
2 #
3 # /etc/fstab
4 # Created by anaconda on Tue Aug 23 16:38:07 2016
5 #
6 # Accessible filesystems, by reference, are maintained under '/dev/disk'
7 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8 #
9 /dev/mapper/centos-root / xfs defaults 0 0
10 UUID=79e2f3d9-4bd1-4b1c-beda-dcac56065789 /boot xfs defaults 0 0
11 /dev/mapper/centos-home /home xfs defaults 0 0
12 /dev/mapper/centos-swap swap swap defaults 0 0
13 /dev/sdc1 /mydata ext4 defaults 0 0
[root@localhost test2]# cat -n /etc/fstab | sed -n '2,3p'
2 #
3 # /etc/fstab
[root@localhost test2]#
2、 -e 選項 意義為多點編輯 也就是-e 后面可以加很多的命令 例如:
如果有這樣一個要求,把/etc/fstab 文件中的所有以#開頭的行都替換成空白 并且把以UUID 開頭的行都刪除
我們的命令需要這樣寫:
[root@localhost test2]# sed -e 's@^#[[:space:]]*@@g' -e '/^UUID/d' /etc/fstab
/etc/fstab
Created by anaconda on Tue Aug 23 16:38:07 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
/dev/mapper/centos-root / xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
/dev/sdc1 /mydata ext4 defaults 0 0
[root@localhost test2]#
3、-f 選項 /PATH/TO/SED_SCRIPT_FILE 每行一個編輯命令 ,可以把-e 的多行編輯命令寫到一個文件里,例如
把剛才上面的例子-e 后面的選項內容寫到文件中,我們可以向下面這樣執行
我們首先用vim 命令創建出一個文本文件,在文本文件中加入剛才-e 后面的命令
s@^#[[:space:]]*@@g
/^UUID/d
然后我們在用下面的-f 選項來執行這個文件就可以了:
[root@localhost test2]# sed -f test.sh /etc/fstab
/etc/fstab
Created by anaconda on Tue Aug 23 16:38:07 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
/dev/mapper/centos-root / xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
/dev/sdc1 /mydata ext4 defaults 0 0
[root@localhost test2]#
最后的執行結果和上面用-e 的執行結果是一樣的
4、-r 支持使用擴展正則表達式
這個比較簡單,這里就不再說明了,就是使用擴展的正則表達式進行匹配
5、-i 選項,比較危險,這個命令是直接邊界源文件的,例如:
[root@localhost test2]# sed -i '/^UUID/d' fstab
[root@localhost test2]# cat fstab
#
# /etc/fstab
# Created by anaconda on Tue Aug 23 16:38:07 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
#
/dev/mapper/centos-root / xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
/dev/sdc1 /mydata ext4 defaults 0 0
[root@localhost test2]#
可以發現fstab 中的以UUID 開頭的文本都刪除了,沒有了,所以一定要注意 不要直接修改源文件,要把源文件備份一份以后在進行修改
3.2 sed 編輯命令
1、d 刪除命令
2、p 顯示模式空間中的內容
3、a \text:在行后面追加文本“text”,支持使用\n實現多行追加;
4、i \text:在行前面插入文本“text”,支持使用\n實現多行插入;
5、c \text:把匹配到的行替換為此處指定的文本“text”;
6、w /PATH/TO/SOMEFILE:保存模式空間匹配到的行至指定的文件中;
7、r /PATH/FROM/SOMEFILE:讀取指定文件的內容至當前文件被模式匹配到的行后面;文件合并;
8、=:為模式匹配到的行打印行號;
9、!:條件取反;
地址定界|編輯命令;
10、s///:查找替換,其分隔符可自行指定,常用的有s@@@, s###等;
替換標記:
g:全局替換;
w /PATH/TO/SOMEFILE:將替換成功的結果保存至指定文件中;
p:顯示替換成功的行;
練習1:刪除/boot/grub/grub2.cfg文件中所有以空白字符開頭的行的行首的所有空白字符;
之前的/boot/grub/grub.conf
[root@localhost test]# sed 's/^[[:space:]]\+//g' /boot/grub/grub.conf
執行后的結果:
練習2:刪除/etc/fstab文件中所有以#開頭的行的行首的#號及#后面的所有空白字符;
練習3:輸出一個絕對路徑給sed命令,取出其目錄,其行為類似于dirname
上述命令就是sed 基本用法,我們也需要了解一下sed的高級用法:
高級編輯命令:
h:把模式空間中的內容覆蓋至保持空間中;
H:把模式空間中的內容追加至保持空間中;
g:把保持空間中的內容覆蓋至模式空間中;
G:把保持空間中的內容追加至模式空間中;
x:把模式空間中的內容與保持空間中的內容互換;
n:覆蓋讀取匹配到的行的下一行至模式空間中;
N:追加讀取匹配到的行的下一行至模式空間中;
d:刪除模式空間中的行;
D:刪除多行模式空間中的所有行;
我們看這樣2個例題:
1、sed ‘1!G;h;$!d’ file 這個命令的執行過程究竟是怎樣的,最后達到一個什么目的,我以一幅圖的形式給大家展示一下執行過程:
2、sed -n ‘1{h;n;x;H;x};p’ filename 這個命令的執行過程是下圖:
以上就是我對于sed 命令的理解。
原創文章,作者:luobo3692003,如若轉載,請注明出處:http://www.www58058.com/49599