什麼是sed?
sed是一種非交互式的流式編輯器,這裏有兩個關鍵字,非交互式和流式
非交互式就是指sed只能夠在命令行下輸入編輯命令來對文本進行編輯,然後在屏幕上查看輸出。
流式是指sed每次只從文件中讀入一行,然後對該行進行指定的處理,並將處理結果輸出到屏幕上,處理完後在讀入下一行。
sed對文本的過程處理如下:
sed的使用
命令格式
sed [options] 'comandstring' file
sed [options] -f script file
//script表示需要對輸入執行的一個或者多個操作指令。
相關選項
-e:表示以選項中指定的script來處理輸入的文件,也就是可以對輸入執行多條指令的意思。
-f :表示以選項中的script文件來處理輸入的文本文件,也就是把sed指令可以寫在文件中。
-n:表示僅僅顯示sed的command處理完後的結果。
相關命令
a:表示在當前行下面插入文本。
i :表示在當前行的上面插入文本。
c:表示把選定的行改爲新的文本。
d:表示刪除經過pattern匹配所選中的行。
D:表示刪除模式空間中的第一行。
s:表示替換指定的字符。
p:表示打印模式空間中的所有行。
P:表示只打印模式空間中的第一行。
q:表示退出sed。
b label:表示跳轉到腳本中帶有標記label的地方,如果標記不存在則跳轉到腳本的末尾。
r file:表示從file中讀取一行。
sed的使用實例
好了,上面講解了sed的命令格式、參數和命令,下面我們來開始進行實戰,對上面的參數和命令來進行測試
指定執行行的地址的範圍(定址)
sed可以對單行或者多行進行處理,如果sed命令前面不指定地址範圍,那麼會默認匹配所有行。
**命令格式:**sed n1[,n2] {sed-command}
其中n1和n2代表行號,可以直接指定數字,或者通過正則表達式來進行匹配。
對指令進行測試的文本如下:
[lzh@leap_ sed_test]$ cat test.c
#include<stdio.h>
int main()
{
start
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
end
return 0;
}
1.首先我們想打印這段文本的第3-第7行:
sed '3,7p' test.c
結果如下:
#include<stdio.h>
int main()
int main()
{
{
start
start
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
end
return 0;
}
這裏我們發現3-7行打印了兩次,而其餘行只打印了一次,因爲sed編輯器默認對命令執行完畢後的處理動作就是打印,而我們在命令字符串中又指定了3-7行再打印一次,所以就會出現上面那種情況;同時這種情況還驗證了sed對文本的處理是一行一行進行的,因爲3-7行的重複打印了兩次。
如果在這裏我們只想打印sed命令處理過的行,那麼我們就需要使用-n選項了
sed -n '3,7p' test.c
執行的結果如下:
[lzh@leap_ sed_test]$ sed -n '3,7p' test.c
int main()
{
start
printf("Hello,World\n");
printf("Hello,World\n");
2.現在我們來驗證一下用正則表達式來進行定址。
我們就把start到end之前的行打印出來吧。
sed -n '/start/, /end/p' test.c
[lzh@leap_ sed_test]$ sed -n '/start/,/end/p' test.c
start
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
printf("Hello,World\n");
end
這裏因爲,和p都有特殊含義,所以我們需要對其用/進行轉義。
通過set對文本進行替換
相關command
/pattern/s/pattern1/pattern2/
/pattern/s/pattern1/pattern2/g
其中,/後面沒有帶g的表示只把通過pattern匹配到的行的第一個pattern1替換成pattern2。
帶g的表示把通過pattern匹配到的行中所有的pattern1替換成pattetn2。
1.我們還是用上面的文本把,這裏我們把start-end之間的printf全部都註釋掉。
[lzh@leap_ sed_test]$ sed -n '/start/,/end/s/printf/\/\/printf/p' test.c
//printf("Hello,World\n");
//printf("Hello,World\n");
//printf("Hello,World\n");
//printf("Hello,World\n");
//printf("Hello,World\n");
//printf("Hello,World\n");
如果想讓註釋在文本中生效,我們可以指定-i選項。
2.下面我們來看看加g和不加g的區別吧。
[lzh@leap_ sed_test]$ cat file
111111111111
222222222222
333333333333
444444444444
222222222222
[lzh@leap_ sed_test]$ sed -n '/2/s/2/~2~/p' file
~2~22222222222
~2~22222222222
[lzh@leap_ sed_test]$ sed -n '/2/s/2/~2~/gp' file
~2~~2~~2~~2~~2~~2~~2~~2~~2~~2~~2~~2~
~2~~2~~2~~2~~2~~2~~2~~2~~2~~2~~2~~2~
應該可以看出來區別的吧~
sed的高級用法
要說sed的高級用法我們就不得不要說一下sed中的兩塊空間了
模式空間(pattern space):表示一個緩衝區,sed讀到的數據只能在模式空間裏面進行相應的處理。
保持空間(hold space):僅僅表示一個緩衝區,數據只是暫時存放在保持空間中,另外保持空間中默認有一個空行。
下面我們來說一下這兩個空間有關的參數吧:
g:將保持空間中的內容拷貝到模式空間中,原來模式空間中的內容被清除。
G:將保持空間中的內容append到模式空間中。
h:將模式空間中的內容拷貝到保持空間中。
H:將模式空間中的內容追加到保持空間中。
d:刪除模式空間中的所有行,並讀入下一行到pattern中。
D:刪除多行模式空間中的第一行,不讀入下一行。
x:交換保持空間和模式空間的內容。
N:以追加方式將文本內容讀取到模式空間中。
## 使用案例
1.我們將列序列轉化成行序列。
[lzh@leap_ sed_test]$ seq 10
1
2
3
4
5
6
7
8
9
10
[lzh@leap_ sed_test]$ seq 10 | sed -n 'H;${x;s/\n/ /g;p}'
1 2 3 4 5 6 7 8 9 10
- 我們倒序輸出序列。
[lzh@leap_ sed_test]$ seq 10
1
2
3
4
5
6
7
8
9
10
[lzh@leap_ sed_test]$ seq 10 | sed -n '1!G;h;$!d;p'
10
9
8
7
6
5
4
3
2
1