一篇文章學會shell工具篇之sed
sed工具執行原理; 有關sed的參數及action的常見操作方法; 定址; 模式空間和保持空間; 使用標簽
1.首先先來了解一下什麽是sed?
sed叫做流編輯器,在shell腳本和Makefile中作為過濾器使用非常普遍,也就是把前一個程序的輸出引入sed的輸入,經過一系列編輯命令轉換成為另一種格式輸出。下面我們通過一張原理圖來了解一下它的工作模式:
編輯命令的格式為,sed /pattern/action
經過sed處理後文件內容並沒有改變,除?使用重定向存儲輸出。sed主要用來自動編輯一個或多個文件;簡化對文件的反復操作;sed默認按照Basic 規範基本匹配!也就是說類似於( ) { } | 等特殊字符需轉義,否則就不識別,或者是用擴展模式也可以。
2. 下面重點介紹一下有關sed的參數及action的操作方法
(1)-n參數,p命令的action
(2) d命令的action
(3)/pattern/s/pattern1/pattern2/:查找符合pattern的行,將該行第一個匹配pattern1的字符串替換為pattern2
/pattern/s/pattern1/pattern2/g:查找符合pattern的行,將該行所有匹配pattern1的字符串替換為pattern2
這個操作不知道大家會不會聯想到vim編輯器中的底行模式搜索,它們是類似的。
下面總結一下sed中參數的選擇及執行操作:
[plain] view plain copy
<strong>參數選擇:
-n:一般sed命令會把所有數據都輸出到屏幕,如果加入-n選項的話,則只會把經過sed命令處理的行輸出到屏幕。
-e:允許對輸入數據應用多條sed命令編輯。
-i:將修改結果直接寫入到讀取數據的文件,而不是由屏幕輸出。(1.修改了文件; 2.由cat可查看)
-f: 指定sed腳本的文件名。
action:
a:追加,在當前行後添加一行或多行。
c:行替換,用c後面的字符串替換原數據行。
i:插入,在當前行前插入一行或多行。
p:打印,輸出指定的行。
s:字符串替換,用一個字符串替換另外一個字符串。格式為”行範圍s/舊字符串/新字符串/g”(如果不加g的話,則表示只替換每行第一個匹配的串)。
</strong>
以上沒有練習到的,有興趣的可以去嘗試嘗試!
3.再來介紹一下sed中的定址
定址用於決定對文件中哪些行進行行編輯,地址的形式可以是數字、正則表達式、或二者的結合。如果沒有指定地址,sed將處理輸入文件的所有行。下面舉一些例子:
sed ‘/start/ ,/end/d‘ file #刪除包含’start’行和’end’行之間的行
sed ‘/start/, 10d‘ file #刪除包含’start’ 的行到第十行的內容
4.模式空間和保持空間
(1)保持空間:用來存儲數據,相當於一個倉庫,它不能對數據進行處理 ;
(2)模式空間:專門以行為單位對數據進行處理。
一般情況下,如果不顯示的使用一些選項的話,是不會用到保持空間的。
[plain] view plain copy
<span style="color:#000000;"><strong>命令:
g:將保持空間的內容拷貝到模式空間中,會將模式空間原來的值覆蓋掉。
G:將保持空間的內容追加到模式空間中。
h:將模式空間的值拷貝到保持空間,會將保持空間原來的值覆蓋掉。
H:將模式空間的值追加到保持空間中。
d:刪除模式空間的所有行,並讀下一行到模式空間。
D:刪除模式空間的第一行,不讀下一行到模式空間。
n:輸出模式空間的行,讀取下一行替換當前模式空間的行,接著執行下一條處理命令而不是第一條命令。
N:讀入下一行,追加到模式空間行後面,此時模式空間中有兩行。
x:交換模式空間和保持空間的內容。
</strong></span>
例1:給每行後面添加一行空行
例2:用sed模擬倒序(tac)打印的過程
例3.追加匹配行到文件末尾
例4:將一列內容變為一行
例5:求出1-100的求和
例6:打印輸出奇數行和偶數行
5.使用標簽
[plain] view plain copy
:a表示標簽a;
ba表示跳轉到a標簽;
$表示最後一行;
!表示不做後續操作
所以,$!ba表示最後一行不用跳轉到a標簽,結束此次操作。
下面舉一個例子:
最後補充一點:
[plain] view plain copy
與grep一樣,sed也支持特殊元字符來進行模式查找、替換。不同的是,sed使用的正則表達式是括在斜杠線"/"之間的模式。
如果要把正則表達式分隔符"/"改為另一個字符,比如o,只要在這個字符前加一個反斜線,在字符後跟上正則表達式,再跟上這個字符即可。例如:sed -n ‘o^56op‘ datafile
^:行首定位符 /^my/ 匹配所有以my開頭的行;
$:行尾定位符 /my$/ 匹配所有以my結尾的行;
.:匹配除換行符以外的單個字符 /m..y/ 匹配包含字母m,後跟兩個任意字符,再跟字母y的行;
*:匹配零個或多個前導字符 /test*/ 匹配包含字符串 tes,後跟零個或多個 t 字母的行;
[]:匹配指定字符組內的任一字符 /t[eE]st/ 匹配包含test 或 tEst 的行;
[^]:匹配不在指定字符組內的任一字符 /t[^eE]st/ 匹配string 以t開頭,但st之前的那個字符不是e或E的行;
&:保存查找串以便在替換串中引用 s/test/*&*/g 符號&代表查找串。test將被替換為*test*
<:詞?首定位符 /<my/ 匹配包含以my開頭的單詞的行;
>:詞尾定位符 /my>/ 匹配包含以my結尾的單詞的行;
x{m}:連續m個x 如:/9{5}/ 匹配包含連續5個9的行;
x{m,}:至少m個x 如:/9{5,}/ 匹配包含至少連續5個9的行;
x{m,n}:至少m個,但不超過n個x 如:/9{5,7}/ 匹配包含連續5到7個9的行。 還有一個單元匹配--替換的問題:
一篇文章學會shell工具篇之sed