vi/vim 的世界裡多了兩個兄弟:sed 和 gawk.

sed: stream editor. 在編輯器處理數據之前,根據事先提供的規則來編輯數據流。

sed 有點類似於 Kafka, 對數據進行一行一行的編輯,行雲流水,沒有半點拖沓。當然 kafka 更加強大,實時捕獲數據,還能指定更複雜的處理邏輯,並且能夠發送到任何地方保存起來。sed 能接受的源頭是文本文件,最終的結果還只能是普通的文本文件,實現的是文本到文本的轉換。

sed 的命令格式:

sed options script file

詳細的文檔見這裡:

gnu.org/software/sed/ma

常用的 3 個可選參數列在這裡:

sed -e s/cat/dog/ logfile.txt
sed -f Wordchange.sed logfile.txt
sed -e s/cat/dog -i logfile.txt

-e : 指定命令表達式,s/cat/dog 用 dog 取代文本中的 cat ;

-f : 如果有多行表達式,且頻繁修改,用文件存儲這些命令表達式則顯得尤為高效,而 -f 代表的就是命令文件;

-i: in-place 就地修改並保存。如果不指定 sed 將修改後的結果輸出到標準輸出也就是屏幕上

主要是圍繞著 script 做文章,指定的命令可以完成目標文本的轉換, 而 options 則更多是一些可選的動作,比如直接修改文本而不是保存,指定多命令的文件等等。

革命要勝利,路線不能歪。所以首先要攻克的便是 script 命令。這裡有份指南,從簡到深,細細鋪開來講。

? sed script overview: sed script overview
? sed commands list: sed commands summary
? The "s" Command: sed』s Swiss Army Knife
? Common Commands: Often used commands
? Other Commands: Less frequently used commands
? Programming Commands: Commands for sed gurus
? Extended Commands: Commands specific of GNU sed
? Multiple commands syntax: Extension for easier scripting

sed 命令腳本綜述

[line address]X[options]

多命令也好,單行命令也好,多行命令也好,命令文件也罷,命令的格式逃不過上面這公式。

line address 是文本的行數範圍,比如指定文本的 30 到 50 行,30,50;

X 是單字命令,夠簡單,但是不好記。隨時備份一張 X 的列表在你的桌面上,或許能幫你隨用隨查; options 就是單字命令的可選參數

sed -e /^foo/d -e s/hello/world/ input.txt > output.txt

echo s/hello/world/ > script2.sed
sed -e /^foo/d -f script2.sed input.txt > output.txt

/^foo 比指定行數(每一行在文本文件中總有一個行號)要來的靈活,^foo代表的就是開頭以foo的那些行;

/d 標識命令是 delete, 即刪除行的操作;

-e, -f, 都可以多次引用,其作用就是為了指定多個命令

sed 常用命令

可選的命令太多了,所以還是挑幾個常用的命令來講講

Swiss Army Knife 瑞士軍刀 - s

[root@centos00 _data]# echo this is a cat dog | sed -e s/cat/fat/
this is a fat dog
[root@centos00 _data]#

s 這單字命令,一定要嚴格按照格式:

s/original word/replaced word/

來編寫,否則出現會這種錯誤:

sed: -e expression #1, char 9: unterminated `s command

其他常用命令介紹

{#;d;q;p;n}

q - quit 在當前行退出(當前處理的文件),不再處理更多往下的行

[root@centos00 _data]# seq 5
1
2
3
4
5
[root@centos00 _data]# seq 5 | sed 3q
1
2
3
[root@centos00 _data]#

seq 是 sequence 命令,產生一組序列值;

3q 是 sed 單字命令應用,3 代表第三行,而 q 就是退出

d - delete 是刪除滿足條件的行,可以指定行號也可以使用條件表達式

[root@centos00 _data]# seq 5 | sed 3d
1
2
4
5
[root@centos00 _data]#

p - print 列印當前行,必須與 sed -n 可選參數同時使用,才奏效

[root@centos00 _data]# seq 5 | sed 3p
1
2
3
3
4
5
[root@centos00 _data]# seq 5 | sed 3p -n
3
[root@centos00 _data]#

-n 作為 sed 的可選參數,沒有在文檔中找到其原意,我暫 YY 它是 no print 的意思。

n - Next line , 隔行處理。指定多少個 n, 就隔多少行處理一次編輯

[root@centos00 _data]# seq 5 | sed n;s/./new line/
1
new line
3
new line
5
[root@centos00 _data]#

[root@centos00 _data]# seq 5 | sed n;n;s/./new line/
1
2
new line
4
5
[root@centos00 _data]#

{#;d;q;p;n} - 命令組合符號{;}

剛才那一案例已經說明白了 n;n;s/./new line/ , 使用「;」即可將多個命令同時作用於一行上,而如果要作用於滿足條件的行,則必須加上「{}」:

[root@centos00 _data]# seq 5 | sed -n 2{s/./new line/;p}
new line
[root@centos00 _data]#

看完這些例子,不禁令我想到一個問題,在單字命令表達式

[line address]X[options] 中,line address 可以是數字型的行號,也可以是滿足條件的行號。而什麼樣的條件可以被放在[line address]表達式中呢?

好比,我需要列印偶數行,表達式該怎麼寫?

固然,用 n 命令可以解決這個問題,但我們考察的是[line address]的用法

# 使用單字命令:

[root@centos00 _data]# seq 8 | sed -n {n;p}
2
4
6
8
[root@centos00 _data]#

使用~可以實現列印隔行的功能:

[root@centos00 _data]# seq 8 | sed -n 0~2p
2
4
6
8

而[line address]還可以使用正則表達式:

[root@centos00 _data]# seq 20 | sed -n /[2]/p
2
12
20
[root@centos00 _data]#

/regular express/ 是正確引用正則表達式的方法,這裡僅僅是列印包含2字元的那些行。

在 IT 領域,僅看理論而不動手,「學而不練」則惘。就像筆者一樣,在玩 Oracle 那段時間天天用著,還蠻熟練的,中途轉 SQL Server 做了幾年,回頭再用 sed 卻手生得緊。拳不離手,曲不離口,文不離碼,一點沒錯。

有 20 道題,是從文檔上看到的,做下筆記,方便日後查閱

  • 1 Joining lines
  • 2 Centering Lines
  • 3 Increment a Number
  • 4 Rename Files to Lower Case
  • 5 Print bash Environment
  • 6 Reverse Characters of Lines
  • 7 Text search across multiple lines
  • 8 Line length adjustment
  • 9 Reverse Lines of Files
  • 10 Numbering Lines
  • 11 Numbering Non-blank Lines
  • 12 Counting Characters
  • 13 Counting Words
  • 14 Counting Lines
  • 15 Printing the First Lines
  • 16 Printing the Last Lines
  • 17 Make Duplicate Lines Unique
  • 18 Print Duplicated Lines of Input
  • 19 Remove All Duplicated Lines
  • 20 Squeezing Blank Lines

推薦閱讀:

相關文章