文件空行處理
1. 在文件中的每一行後面添加一個空行。正則表達式
sed 'G' test.txt
解釋: Get命令是將保留空間的內容取出,並添加到當前模式空間的內容以後(添加一行)。當保留空間爲空時,效果爲往模式空間添加一行空行。post
2. 保證文件中的每一行後面都有一行空行。和1不一樣的是,若是文件中自己包含空行,則合併成一行。spa
sed '/^$/d;G' test.txt
解釋:首先刪除空行,再添加一行空行。code
3. 刪除偶數行get
sed 'n;d' test.txt
解釋:n的意思讀入下一行,而且輸出當前行。當n讀入下一行以後,用d將其刪除。ast
4. 在匹配regex的行以前添加空行class
sed '/regex/{x;p;x}' test.txt
解釋:x的意思是交換保留空間和模式空間的內容,首先保留空間爲空,首次交換並用p打印空行;接着將原有內容交換回來,執行到命令末尾,自動輸出模式空間的內容。test
5. 在匹配regex的行以後添加空行效率
sed '/regex/G' test.txt
解釋:參考1基礎
6. 在匹配regex的行以前和以後都添加空行
sed '/regex/{x;p;x;G;}' test.txt
解釋:參考四、5
7. 每五行後添加一行空行
sed 'n;n;n;n;G'
或者
sed '0~5G' test.txt
解釋:很簡單,每次讀5行,再添加一個空行。第二種方法利用了GNU Sed的功能 addr~step,查看man sed。
文件行號處理
1. 給每一行添加行號,而且行號與行的非空白內容之間以製表符(t)分隔(保證左對齊)
相似:
1 aaa 20 aaa
相應的命令以下:
sed '=' test.txt | sed 'N;s/s*ns*/t/'
解釋:首先要取出並打印行號,能夠用=命令打印行號,可是此時行號與行內容不在同一行輸出,所以須要將標準輸出重定向再次使用sed命令處理。使用Next命令讀入下一行,並將n(包括多餘的空白)替換成一個製表符(t),再默認輸出打印。準確地說,這裏使用了兩條sed命令。
2. 給每一行添加行號,而且行號與行的非空白內容之間以製表符(t)分隔(保證右對齊)
相似:(假設行號最可能是3位數)
1 aaa 20 aaa 123 aaa
相應的命令以下:
sed '=' test.txt | sed 'N; s/^/ /;s/ *([ 0-9]{3})s*ns*/1t/'
解釋:前面同1,這裏只介紹後面這部分:s/^/ /;s/ *([ 0-9]{3})s*ns*/1t/
這裏首先在行首插入兩個空格,而後將空格與後面的行號(數字)部分,只保留三個字符。最後將回車與多餘的空白替換成製表符。
3. 給文件每一行加上行號,可是僅當行非空時纔打印行號。
sed '/./=' test.txt | sed '/./N; s/s*ns*/t/'
解釋:在sed中.不匹配n,所以用/./匹配非空行,其它同1。 可是若是要處理空行(包含空白符等的行),則須要:
sed '/[^[:blank:]]/=' test.txt | sed '/[^[:blank:]]/N; s/n/t/'
4. 統計行數
sed -n '$=' test.txt
解釋:使用-n阻止默認輸出,並只在最後一行的時候打印行號。
文本內容轉換和替換
1. 在Unix環境下,轉換DOS換行符爲Unix格式
sed 's/^M//' test.txt
解釋:^M的鍵入方法,按住ctrl+v再敲回車。 這種處理和環境依賴性比較大,不是很是統一,這裏只介紹一種。
2. 刪除行首和行尾空白
sed 's/^[[:blank:]]*|[[:blank:]]*$//' test.txt
解釋:這裏再次用到了posix字符組,很少解釋。
3. 對每一行按照79列寬處理, 保持右對齊
相似
...................a .................bba ................cccc
(超出的部分不處理)
sed -e ':a' -e 's/^.{1,78}$/ &/;ta' test.txt
解釋: 對單個命令自己不解釋了,這裏用到了標籤、跳轉、替換等命令。 替換過程對不小於79列寬的行處理,在行首插入一個空格,直到等於79列寬爲止,自動
輸出。
4. 對每一行按照79列寬處理,保持居中。
sed -e ':a' -e 's/^.{1,77}$/ & /; ta' test.txt
解釋:同3
5. 在每一行用bar替換foo
a. sed 's/foo/bar/' test.txt b. sed 's/foo/bar/4' test.txt c. sed 's/foo/bar/g' test.txt d. sed 's/(.*)foo(.*foo)/1bar2/ test.txt e. sed 's/(.*)foo/1bar/' test.txt
解釋:a在一行中只替換一次(首次出現);b替換第四次出現;c全局替換;d替換倒數第二個匹配;e替換最後一個匹配 。
6. 在包含或者不包含baz的行中替換foo爲bar
sed '/baz/s/foo/bar/g' test.txt
sed '/baz/!s/foo/bar/g' test.txt
7. 反轉文件行的順序(相似tac命令,即從最後一行到第一行的順序打印)
sed '1!G;h;$!d' test.txt
解釋:首先1!G表示將除第一行以外,都先從保留空間取出內容並追加到模式空間的最後;h表示將模式空間的內容所有覆蓋到保留空間;而後 $!d表示將除最後一行以外的,都要將模式空間清除,並從頭開始(不打印)。這些命令合起來就是,首先將一行的內容拷貝到臨時緩衝區(保留空間),而後清除當前行(不打印),再讀入下一行並從緩衝區取會保存的內容,所以行的順序就顛倒了。
8. 反轉文件中每一行的字符順序(相似rev命令)
sed '/n/!G;s/(.)(.*n)/&21/;//D;s/.//'
解釋:首先解釋一下這裏使用到的一些特殊語法,//D
,//爲無內容,這是一種簡寫狀況,默認使用上一次使用的正則表達式,這裏就是(.)(.*n)
,所以等價於/(.)(.*n)/D
。這條sed命令中過程是這樣的,首先該行若是不包含回車,則在末尾添加一個,對應命令中的/n/!G
;而後開始替換,目的是把當前最前面的字母放到後面。
例如123n變成123n23n1;23n1變成23n3n21。而後使用D命令刪除第一行的內容。最後一個替換去掉首字符。該例子能夠本身使用一個簡單的例子演練一遍就清楚了。
9. 將兩行合併成一行(相似paste命令)
sed '$!N;s/n/ /' test.txt
解釋:$!N表示除最後一行外,其它每行在讀入的時候,都將下一行讀進來添加到後面。接着用替換命令替換回車爲空格。若是$!N改爲N在這裏不會出現問題,可是要記住的是,當到最後一行時,執行N命令將不會再讀入新行,結果是sed退出。不會執行接下來的命令。
10. 若是一行以「」結束,則合併下一行內容到當前行以後。
sed -e ':a' -e '/$/N; s/n/ /; ta' test.txt
解釋:同8相似,可是要考慮合併多行,所以須要作循環處理,這裏使用標籤來達到這個目的。
11. 若是一行以等號開始,則合併這一行至上一行,並替換等號爲空格
sed -e ':a' -e '$!N;s/n=/ /;ta;P;D' test.txt
解釋:同9相似,不過這裏要讀入下一行以後,判斷'n='則替換成空格, 若是替換成功,則繼續讀入下一行(標籤跳轉);不然, 打印並刪除模式空間中的第一行。
D命令不會導入新的行讀入。
12. 給數字串加逗號,例如把「1234567」變成「1,234,567」
sed -e ':a' -e 's/([0-9])([0-9]{3})($|,)/1,2/;ta' test.txt
或者
sed -e ':a' -e 's/(.*[0-9])([0-9]{3})/1,2/;ta' test.txt
解釋:這裏要使用標籤進行循環處理,關鍵點在正則表達式的書寫上。第二種寫法更加簡練。
13. 給帶有小數點和鉛的數字加上逗號
sed ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/12,3/g;ta' test.txt
或者
sed ':a;s/^(-?[0-9]+)([0-9]{3})/1,2/g;ta' test.txt
解釋:同11,要注意負號和小數點,所以要加上開始標記^和-。
選擇性輸出行
1. 打印一個文件的前10行(相似head命令)
sed -n '1,10p' test.txt
或者
sed '10q' test.txt
解釋:顯然第二種方法比第一種方法效率高。q退出命令,代表在第10行的時候自動退出,再也不讀入新的輸入行。
2. 打印一個文件的第一行。
sed 'q' test.txt
解釋:同上,在讀入第一行以後就退出,可是仍打印第一行的內容。
3. 打印一個文件的倒數10行(相似tail命令)
sed ':a;$q;N;11,$D;ba'
解釋:若是隻看 ':a;$q;N;ba',效果就是一直將下一行追加到模式空間,最後達到最後一行的時候退出,並打印模式空間的內容。可是當變成':a;$q;N;11,$D;ba',11,$D表示若是行超過10行,則將模式空間的第一行刪除,同時ba跳轉到開頭,再次讀入下一行,保持模式空間的行數在10行。這樣看起來就是模式空間的最前面的一行被刪除,同時將新的一行追加到末尾處,當循環結束時,模式空間中保存的就是文件的最後10行。
4. 打印一個文件的倒數兩行(相似tail -2)
sed ':a;$q;N;3,$D;ba'
或者
sed '$!N;$!D' test.txt
解釋:第一種方法同3同樣。第二種方法,$!的意思是不在最後一行上執行命令。N命令不解釋,D命令是刪除模式空間的第一行,而且跳轉到命令開頭從新執行,而且當模式空間仍有內容時,不讀入新的輸入行。這一句的意思透露出兩點:
1) D命令以後的命令不會執行,而是跳轉到開頭,同時也不會自動輸出當前模式空間的內容。
2) 模式空間不爲空,則不會自動讀入下一行的數據,除非使用N命令讀入下一行。
所以,$!N;$!D,將下一行讀入模式空間,而且將模式空間的第一行刪除,除非遇到最後一行,所以當循環結束時,模式空間中包含倒數兩行,完成要求,打印輸出。
5. 打印一個文件的最後一行(相似tail -1)
sed ':a;$q;N;2,$D;ba' test.txt
或者
sed -n '$p' test.txt
或者
sed '$!d' test.txt
6. 打印匹配「regex」行(相似grep)
sed -n '/regex/p' test.txt
或者
sed '/regex/!d' test.txt
解釋:同5相似
7. 打印不匹配「regex」行(相似grep -v)
sed -n '/regex/!p' test.txt
或者
sed '/regex/d' test.txt
解釋:同6。
8. 打印匹配「regex」以前的那一行。
sed -n '$!N;/regex/!D;/regex/P'
或者
sed -n '/regex/{g;1!p;};h'
解釋:第一方法理解起來比較簡單,讀入下一行到模式空間,而且判斷是否包含regex,若是匹配,則打印模式空間中的第一行,若是不匹配,則刪除模式空間的第一行,循環處理。(這種方法有問題嗎?)
第二種方法,若是沒遇到匹配行,則將當前行拷貝到保持空間,而後讀入下一行,若是匹配,則將保存的行從保持空間中提取到模式空間,而且打印(假如第一行就匹配則不打印)。
9. 打印奇數行
sed -n 'N;P' test.txt
或者
sed -n '1~2p' test.xt
解釋:第一種方法,N讀入下一行到模式空間,P打印模式空間中的第一行,而後自動輸出被關閉,進入下一次循環,從新讀入新的一行到模式空間(自動讀入新行,非N,所以模式空間的內容被清除再讀入新行),再執行N;P,一樣打印模式空間的第一行。效果等同於打印奇數行。第二種方法,比較簡單,不過用到GNU Sed的特殊地址表示方法,addr~step,所以只在1,3,5,7等奇數行纔打印行的內容。
10. 打印匹配「regex」那一行的後一行。
sed -n '/regex/{n;p}' test.txt
解釋:若是找到匹配的行,則讀取下一行,而且打印輸出。
11. 打印匹配「regex」那一行的先後一行,而且打印匹配行的行號(相似grep -A1 -B1)
sed -n '/regex/{=;x;1!p;g;$!N;p;D;}; h' test.txt
解釋: 若是不匹配,則先把該行保存到保持空間暫時記錄下來;若是找到匹配行,則打印該行的等號,而且將模式空間的內容和保持空間的內容交換,隨即打印模式空間的內容(第一行除外,同10);交換以後,再次將保持空間的內容恢復到模式空間(即當前匹配行),再讀入下一行(注意$!N),打印模式空間的全部內容(非P),打印完以後,清除模式空間的第一行的內容。進入下一個循環。注意此時,保持空間一樣保存着當前的輸入行。
12. 假設段落以空行分隔,打印包含「regex」的段落。
sed '/./{H;$!d};x;/regex/!d' test.txt
sed '/./{1h;1!H;$!d};x;/regex/!d' test.txt
解釋:思路很簡單,首先將讀入段落的內容,並依次將段落的第一行追加到保持空間備份,而後在保持空間中查找匹配單詞。可是第一種方法的輸出結果會在開始處多一個空行,第二種方法的目的是去掉多輸出的一個空行。
13. 打印長於65個字符的行
sed -n '/^.{65}/p' test.txt
解釋:正則表達式的應用。
14. 打印第52行
sed '52q;d' test.txt
解釋:效率比通常方法高
15. 從第三行開始,每隔7行打印機一行
sed -n '3~7p' test.txt
sed -n '3,${p;n;n;n;n;n;n;}' test.txt
解釋:比較簡單
選擇性刪除某些行
1. 刪除文件中連續而且重複的行,只保留第一行(相似uniq命令)
sed -n "$!N;/^(.*)n1$/!P;D' test.txt
解釋:讀入下一行,而後用正則判斷兩行是否同樣,若是同樣,則不打印,而且刪除一樣行中的第一行,再循環處理。
2. 刪除文件中重複的,但不連續的行,注意不要溢出保持空間的緩衝區大小。
不知道
3. 刪除一個文件中前10行
sed '1,10d' test.txt
解釋:比較簡單
4. 刪除一個文件中最後1行
sed '$d' test.txt
5. 刪除一個文件中最後2行
sed 'N;$!P;$!D;$d' test.txt
解釋:使用N讀入一行,而且若是新讀入的下一行不是最後一行,則打印模式空間中的第一行,而且刪除;若是新讀入的一行是文件的最後一行,則刪除模式空間中的全部內容(即倒數兩行)。
6. 刪除一個文件中最後10行;
sed ':a;$d;N;11,${P;D};ba' test.txt
sed ':a;$d;N;2,10ba;P;D' test.txt
sed -n ':a;1,10!{P;N;D};N;ba'
解釋:第一種方法參考前面的打印文件的最後10行內容。第二種方法,首先不停讀入下一行的內容,直到讀入第11行,此時模式空間中包含11行,打印第一行的內容並刪除,而後判斷最後讀入的那一行是否是最後一行,若是是,則刪除模式空間中的內容(一共10行,即倒數10行);若是不是,則繼續讀入下一行,打印模式空間中的第一行並刪除。循環直到最後一行爲止。第一種方法,首先將讀入前10行的內容,若是讀到第10行以後(11行開始),首先打印模式空間的第一行,並讀入下一行,再刪除第一行,循環處理;始終保證模式空間中包含10行的內容,當在最後一行以後,再讀新行會致使sed退出,並打印模式空間的內容。
7. 每8行刪除1行
sed '0~8d' test.txt
解釋:比較簡單。
8. 刪除全部空行
sed '/^$/d' test.txt
或者
sed '/./!d' test.txt
解釋:都比較簡單,第一個匹配空行,第二個匹配非空行。
9. 壓縮文件中的連續空行爲一行,包括文件開頭和結尾(相似cat -s)
sed '/^$/N;/n$/D' test.txt
解釋:遇到空行,則繼續讀入下一行,若是讀入的一行依然是空行,則刪除第一行(空行),循環處理。
10. 刪除文件中的連續空行,但保留前兩個空行
sed '/^$/N;/n$/N;//D' test.txt
解釋:同9,不過不是壓縮空行爲一行,而是兩行,所以在9的基礎上再加一步,//D中正則爲空,默認使用上次的正則表達式。
11. 刪除文件開頭的空行
sed '/./, $!d' test.txt
解釋:刪除第一行非空行以前的全部空行。
12. 刪除文件結尾的全部空行
sed ':a;/^n*$/{$d;N;ba}' test.txt
解釋:若是碰到一個空行,若是不是最後一行,則繼續讀入下一行,跳到開頭,判斷模式空間內是否全是空行。若是讀到最後一行,並且,模式空間內的內容都是空行,則刪除,這意味着刪除了全部結尾處的空行。
13. 刪除每一個段落的最後一行
sed -n '/^$/{p;h;};/./{x;/./p}' test.txt
解釋:若是遇到空行,則直接打印,而且將空行保存到保持空間,這樣會覆蓋空行的上一行內容,若是上一行不爲空行,內容就不打印了,而若是上一行是空行,由於以前已經打印了,因此這裏不會有影響;若是不是空行,則交換保持空間和模式空間的內容,保持空間保存的是上一行的內容,若是上一行不是空行,則打印。