熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> 嵌入式開發 >> 正文

SED單行腳本快速參考(流編輯器)第1/2頁

2022-06-13   來源: 嵌入式開發 
sed (stream editor)

  功能說明利用script來處理文本文件
語法sed [hnV][e<script>][f<script文件>][文本文件]
補充說明sed可依照script的指令來處理編輯文本文件
參數
e<script>或expression=<script> 以選項中指定的script來處理輸入的文本文件
f<script文件>或file=<script文件> 以選項中指定的script文件來處理輸入的文本文件
h或help 顯示幫助
n或quiet或silent 僅顯示script處理後的結果

  V或version 顯示版本信息

sed工作原理

  sed是一個非交互式的流編輯器所謂非交互式是指使用sed只能在命令行下輸入編輯命令來編輯文本然後在屏幕上查看輸出而所謂流編輯器是指sed每次只從文件(或輸入)讀入一行然後對該行進行指定的處理並將結果輸出到屏幕(除非取消了屏幕輸出又沒有顯式地使用打印命令)接著讀入下一行整個文件像流水一樣被逐行處理然後逐行輸出

  下面我們看一下sed的工作過程

  sed不是在原輸入上直接進行處理的而是先將讀入的行放到緩沖區中對緩沖區裡的內容進行處理處理完畢後也不會寫回原文件(除非用shell的輸出重定向來保存結果)而是直接輸出到屏幕上sed運行過程中維護著兩個緩沖區一個是活動的模式空間(pattern space)另一個是起輔助作用的暫存緩沖區(holding space)一般情況下每當運行sedsed首先把第一行裝入模式空間進行處理後輸出到屏幕然後將第二行裝入模式空間替換掉模式空間裡原來的內容然後進行處理以此類推

  

  

  一般情況下暫存緩沖區是用不到的但有特殊的命令可以在模式空間與暫存緩沖區之間交換數據後文將有介紹由於sed對文本的所有操作都是在緩沖區裡進行的所以不會對原文件造成任何破壞

  sed命令格式

  sed的命令格式如下

sed [Options] [Commands] filename

其中Command是一個sed命令sed命令一定要被包含在一對單引號中以免被shell解釋其格式如下

[addressrange][sedcommand]或
[Patterntomatch][sedcommand]

addressrange是指要處理的行的范圍又叫地址范圍patterntomatch是一個要匹配的模式是一個正則表達式sedcommand是一個sed命令用來對指定的行進行處理下面是一個簡單的例子

sed –n p students

這個命令將文件students中的第行打印到屏幕注意地址范圍和sed命令之間沒有空格如果加入空格sed也會將其忽略參數n用來取消默認輸出默認情況下sed每讀入一行到模式空間無論是否對其進行處理在讀入下一行之前多要將模式空間中的內容輸出到屏幕上參數n可以用來取消這種默認的輸出只有當用戶用命令p時才將指定的行輸出到屏幕如果沒有用參數n而又對指定行執行了p命令那麼這些行將會被打印兩次

地址范圍可以是一個數字這個數字代表了一個行號也可以是一個用逗號分隔的兩個數字表示的范圍(包括這兩行)范圍可以是數字正則表達式或是兩者的組合

patterntomatch是一個要匹配的模式sed將會對所有匹配的行執行sedcommand其實這裡的patterntomatch也可以看作是一個地址這個地址是所有與指定模式匹配的行的行號因此sed的格式可以歸納為一種

sed [Options] [addressrange][sedcommand] filename

  文本間隔

  # 在每一行後面增加一空行
sed G
# 將原來的所有空行刪除並在每一行後面增加一空行
# 這樣在輸出的文本中每一行後面將有且只有一空行
sed /^$/d;G
# 在每一行後面增加兩行空行
sed G;G
# 將第一個腳本所產生的所有空行刪除(即刪除所有偶[奇]數行)
sed n;d
# 在匹配式樣regex的行之前插入一空行
sed /regex/{x;p;x;}

  # 在匹配式樣regex的行之後插入一空行
sed /regex/G
# 在匹配式樣regex的行之前和之後各插入一空行
sed /regex/{x;p;x;G;}

  編號

  # 為文件中的每一行進行編號(簡單的左對齊方式)這裡使用了制表符
# (tab見本文末尾關於\t的用法的描述)而不是空格來對齊邊緣
sed = filename | sed N;s/\n/\t/
# 對文件中的所有行編號(行號在左[上]文字右[左]端對齊)
sed = filename | sed N; s/^/ /; s/ *\(\{\}\)\n/\ /
# 對文件中的所有行編號但只顯示非空白行的行號
sed //= filename | sed //N; s/\n/ /
# 計算行數(模擬wc l
sed n $=

  文本轉換和替代

  # Unix環境轉換DOS的新行符(CR/LF)為Unix格式
sed s/$//                                                                                    # 假設所有行以CR/LF結束
sed s/^M$// # 在bash/tcsh中將按CtrlM改為按CtrlV
sed s/\xD$//                                                                            # ssedgsed 及更高版本
# Unix環境轉換Unix的新行符(LF)為DOS格式
sed s/$/`echo e \\\r`/                                                              # 在ksh下所使用的命令
sed s/$/`echo \\\r`/                                                                # 在bash下所使用的命令
sed s/$/`echo \\\r`/                                                                  # 在zsh下所使用的命令
sed s/$/\r/                                                                                  # gsed 及更高版本

  # DOS環境轉換Unix新行符(LF)為DOS格式
sed s/$//                                                                                  # 方法
sed n p                                                                                    # 方法
# DOS環境轉換DOS新行符(CR/LF)為Unix格式
# 下面的腳本只對UnxUtils sed 及更高版本有效要識別UnxUtils版本的
# sed可以通過其特有的text選項你可以使用幫助選項(help)看
# 其中有無一個text項以此來判斷所使用的是否是UnxUtils版本其它DOS
# 版本的的sed則無法進行這一轉換但可以用tr來實現這一轉換
sed s/\r// infile >outfile                                                        # UnxUtils sed v 或更高版本
tr d \r <infile >outfile                                                              # GNU tr 或更高版本
# 將每一行前導的空白字符(空格制表符)刪除
# 使之左對齊
sed s/^[ \t]*//                                                                          # 見本文末尾關於\t用法的描述
# 將每一行拖尾的空白字符(空格制表符)刪除
sed s/[ \t]*$//                                                                          # 見本文末尾關於\t用法的描述

  # 將每一行中的前導和拖尾的空白字符刪除
sed s/^[ \t]*//;s/[ \t]*$//
# 在每一行開頭處插入個空格(使全文向右移動個字符的位置)
sed s/^/ /
# 以個字符為寬度將所有文本右對齊
sed e :a e s/^\{\}$/ &/;ta                                                            # 個字符外加最後的一個空格
# 以個字符為寬度使所有文本居中在方法為了讓文本居中每一行的前
# 頭和後頭都填充了空格在方法在居中文本的過程中只在文本的前面填充
# 空格並且最終這些空格將有一半會被刪除此外每一行的後頭並未填充空格

  sed e :a e s/^\{\}$/ & /;ta                                                            # 方法
sed e :a e s/^\{\}$/ &/;ta e s/\( *\)\/\/                                    # 方法
# 在每一行中查找字串foo並將找到的foo替換為bar
sed s/foo/bar/                                                                                        # 只替換每一行中的第一個foo字串
sed s/foo/bar/                                                                                      # 只替換每一行中的第四個foo字串
sed s/foo/bar/g                                                                                      # 將每一行中的所有foo都換成bar
sed s/\(*\)foo\(*foo\)/\bar\/                                                              # 替換倒數第二個foo
sed s/\(*\)foo/\bar/                                                                              # 替換最後一個foo
# 只在行中出現字串baz的情況下將foo替換成bar
sed /baz/s/foo/bar/g
# 將foo替換成bar並且只在行中未出現字串baz的情況下替換
sed /baz/!s/foo/bar/g

  # 不管是scarletruby還是puce一律換成red
sed s/scarlet/red/g;s/ruby/red/g;s/puce/red/g                                #對多數的sed都有效
gsed s/scarlet\|ruby\|puce/red/g                                                      # 只對GNU sed有效
# 倒置所有行第一行成為最後一行依次類推(模擬tac
# 由於某些原因使用下面命令時HHsed v會將文件中的空行刪除
sed !G;h;$!d                                                                                      # 方法
sed n !G;h;$p                                                                                  # 方法
# 將行中的字符逆序排列第一個字成為最後一字……(模擬rev
sed /\n/!G;s/\(\)\(*\n\)/&\\/;//D;s///
# 將每兩行連接成一行(類似paste
sed $!N;s/\n/ /

  # 如果當前行以反斜槓\結束則將下一行並到當前行末尾
# 並去掉原來行尾的反斜槓
sed e :a e /\\$/N; s/\\\n//; ta
# 如果當前行以等號開頭將當前行並到上一行末尾
# 並以單個空格代替原來行頭的=
sed e :a e $!N;s/\n=/ /;ta e P;D
# 為數字字串增加逗號分隔符號改為
gsed :a;s/\B[]\{\}\>/&/;ta                                                          # GNU sed
sed e :a e s/\(*[]\)\([]\{\}\)/\\/;ta                                  # 其他sed
# 為帶有小數點和負號的數值增加逗號分隔符(GNU sed)
gsed r :a;s/(^|[^])([]+)([]{})/\\\/g;ta
# 在每行後增加一空白行(在第等行後增加一空白行)
gsed ~G                                                                                      # 只對GNU sed有效
sed n;n;n;n;G;                                                                                  # 其他sed

  選擇性地顯示特定行

  # 顯示文件中的前行(模擬head的行為)
sed q
# 顯示文件中的第一行(模擬head 命令)
sed q
# 顯示文件中的最後行(模擬tail
sed e :a e $q;N;$D;ba

  # 顯示文件中的最後行(模擬tail 命令)
sed $!N;$!D
# 顯示文件中的最後一行(模擬tail
sed $!d                                                                                    # 方法
sed n $p                                                                                # 方法
# 顯示文件中的倒數第二行
sed e $!{h;d;} e x                                                                # 當文件中只有一行時輸入空行
sed e {$q;} e $!{h;d;} e x                                              # 當文件中只有一行時顯示該行
sed e {$d;} e $!{h;d;} e x                                              # 當文件中只有一行時不輸出
# 只顯示匹配正則表達式的行(模擬grep
sed n /regexp/p                                                                    # 方法
sed /regexp/!d                                                                        # 方法
# 只顯示匹配正則表達式的行(模擬grep v
sed n /regexp/!p                                                                  # 方法與前面的命令相對應
sed /regexp/d                                                                        # 方法類似的語法

  # 查找regexp並將匹配行的上一行顯示出來但並不顯示匹配行
sed n /regexp/{g;!p;};h
# 查找regexp並將匹配行的下一行顯示出來但並不顯示匹配行
sed n /regexp/{n;p;}
# 顯示包含regexp的行及其前後行並在第一行之前加上regexp
# 在行的行號(類似grep A B
sed n e /regexp/{=;x;!p;g;$!N;p;D;} e h
# 顯示包含AAABBBCCC的行(任意次序)

  sed /AAA/!d; /BBB/!d; /CCC/!d                                                # 字串的次序不影響結果
# 顯示包含AAABBBCCC的行(固定次序)
sed /AAA*BBB*CCC/!d
# 顯示包含AAABBBCCC的行(模擬egrep
sed e /AAA/b e /BBB/b e /CCC/b e d                            # 多數sed
gsed /AAA\|BBB\|CCC/!d # 對GNU sed有效
# 顯示包含AAA的段落(段落間以空行分隔)
# HHsed v 必須在x;後加入G;接下來的個腳本都是這樣
sed e //{H;$!d;} e x;/AAA/!d;
# 顯示包含AAABBBCCC三個字串的段落(任意次序)
sed e //{H;$!d;} e x;/AAA/!d;/BBB/!d;/CCC/!d
# 顯示包含AAABBBCCC三者中任一字串的段落(任意次序)
sed e //{H;$!d;} e x;/AAA/b e /BBB/b e /CCC/b e d
gsed //{H;$!d;};x;/AAA\|BBB\|CCC/b;d                              # 只對GNU sed有效

  # 顯示包含個或以上字符的行
sed n /^\{\}/p
# 顯示包含個以下字符的行
sed n /^\{\}/!p                                                                  # 方法與上面的腳本相對應
sed /^\{\}/d                                                                        # 方法更簡便一點的方法
# 顯示部分文本——從包含正則表達式的行開始到最後一行結束
sed n /regexp/$p
# 顯示部分文本——指定行號范圍(從第至第行)

  sed n p                                                                        # 方法
sed !d                                                                            # 方法
# 顯示第
sed n p                                                                          # 方法
sed !d                                                                              # 方法
sed q;d                                                                            # 方法 處理大文件時更有效率
# 從第行開始行顯示一次
gsed n ~p                                                                      # 只對GNU sed有效
sed n ${p;n;n;n;n;n;n;}                                                  # 其他sed
# 顯示兩個正則表達式之間的文本(包含)
sed n /Iowa//Montana/p                                                  # 區分大小寫方式

  選擇性地刪除特定行

  # 顯示通篇文檔除了兩個正則表達式之間的內容
sed /Iowa//Montana/d
# 刪除文件中相鄰的重復行(模擬uniq
# 只保留重復行中的第一行其他行刪除
sed $!N; /^\(*\)\n\$/!P; D
# 刪除文件中的重復行不管有無相鄰注意hold space所能支持的緩存
# 大小或者使用GNU sed
sed n G; s/\n/&&/; /^\([ ~]*\n\)*\n\/d; s/\n//; h; P
# 刪除除重復行外的所有行(模擬uniq d
sed $!N; s/^\(*\)\n\$/\/; t; D

  # 刪除文件中開頭的
sed d
# 刪除文件中的最後一行
sed $d
# 刪除文件中的最後兩行
sed N;$!P;$!D;$d
# 刪除文件中的最後
sed e :a e $d;N;ba e P;D                                            # 方法
sed n e :a e !{P;N;D;};N;ba                                          # 方法
# 刪除的倍數行
gsed ~d                                                                                  # 只對GNU sed有效
sed n;n;n;n;n;n;n;d;                                                                    # 其他sed
# 刪除匹配式樣的行
sed /pattern/d                                                                              # 刪除含pattern的行當然pattern
                                                                                                # 可以換成任何有效的正則表達式

  # 刪除文件中的所有空行(與grep 效果相同)
sed /^$/d # 方法
sed //!d # 方法
# 只保留多個相鄰空行的第一行並且刪除文件頂部和尾部的空行
# (模擬cat s
sed ///^$/!d                                                                                #方法刪除文件頂部的空行允許尾部保留一空行
sed /^$/N;/\n$/D                                                                        #方法允許頂部保留一空行尾部不留空行

  # 只保留多個相鄰空行的前兩行
sed /^$/N;/\n$/N;//D
# 刪除文件頂部的所有空行
sed //$!d
# 刪除文件尾部的所有空行
sed e :a e /^\n*$/{$d;N;ba e }                                          # 對所有sed有效
sed e :a e /^\n*$/N;/\n$/ba                                                  # 同上但只對gsed *有效
# 刪除每個段落的最後一行
sed n /^$/{p;h;};//{x;//p;}

  特殊應用

  # 移除手冊頁(man page)中的nroff標記在Unix System V或bash shell下使
# 用echo命令時可能需要加上e 選項
sed s/`echo \\\b`//g                                                              # 外層的雙括號是必須的(Unix環境)
sed s/^H//g                                                                              # 在bash或tcsh中 按CtrlV 再按CtrlH
sed s/\x//g                                                                          # sed GNU sedssed所使用的十六進制的表示方法
# 提取新聞組或email 的郵件頭
sed /^$/q                                                                                  # 刪除第一行空行後的所有內容
# 提取新聞組或email 的正文部分
sed /^$/d                                                                              # 刪除第一行空行之前的所有內容
# 從郵件頭提取Subject(標題欄字段)並移除開頭的Subject:字樣
sed /^Subject: */!d; s///;q

  # 從郵件頭獲得回復地址
sed /^ReplyTo:/q; /^From:/h; //d;g;q
# 獲取郵件地址在上一個腳本所產生的那一行郵件頭的基礎上進一步的將非電郵
# 地址的部分剃除(見上一腳本)
sed s/ *(*)//; s/>*//; s/*[:<] *//
# 在每一行開頭加上一個尖括號和空格(引用信息)
sed s/^/> /
# 將每一行開頭處的尖括號和空格刪除(解除引用)
sed s/^> //
# 移除大部分的HTML標簽(包括跨行標簽)
sed e :a e s/<[^>]*>//g;/</N;//ba
# 將分成多卷的uuencode文件解碼移除文件頭信息只保留uuencode編碼部分
# 文件必須以特定順序傳給sed下面第一種版本的腳本可以直接在命令行下輸入
# 第二種版本則可以放入一個帶執行權限的shell腳本中(由Rahul Dhesi的一
# 個腳本修改而來

  sed /^end//^begin/d file file fileX | uudecode                                  # vers
sed /^end//^begin/d $@ | uudecode                                                        # vers
# 將文件中的段落以字母順序排序段落間以(一行或多行)空行分隔GNU sed使用
# 字元\v來表示垂直制表符這裡用它來作為換行符的占位符——當然你也可以
# 用其他未在文件中使用的字符來代替它
sed //{H;d;};x;s/\n/={NL}=/g file | sort | sed s/={NL}=//;s/={NL}=/\n/g
gsed //{H;d};x;y/\n/\v/ file | sort | sed s/\v//;y/\v/\n/
# 分別壓縮每個TXT文件壓縮後刪除原來的文件並將壓縮後的ZIP文件
# 命名為與原來相同的名字(只是擴展名不同)(DOS環境dir /b

  # 顯示不帶路徑的文件名)
echo @echo off >zipupbat
dir /b *txt | sed s/^\(*\)\TXT/pkzip mo \ \TXT/ >>zipupbat
使用SEDSed接受一個或多個編輯命令並且每讀入一行後就依次應用這些命令
當讀入第一行輸入後sed對其應用所有的命令然後將結果輸出接著再讀入第二行輸入對其應用所有的命令……並重復這個過程上一個例子中sed由標准輸入設備(即命令解釋器通常是以管道輸入的形式)獲得輸入在命令行給出一個或多個文件名作為參數時這些文件取代標准輸入設備成為sed的輸入sed的輸出將被送到標准輸出(顯示器)因此
cat filename | sed q                                                                    # 使用管道輸入
sed q filename                                                                            # 同樣效果但不使用管道輸入
sed q filename > newfile                                                            # 將輸出轉移(重定向)到磁盤上

  要了解sed命令的使用說明包括如何通過腳本文件(而非從命令行)來使用這些命令請參閱《sed & awk》第二版作者Dale Dougherty和Arnold Robbins(OReilly《UNIX Text Processing》 作者Dale Dougherty和Tim OReilly(Hayden Books)或者是Mike Arst寫的教程——壓縮包的名稱是USEDITZIP(在許多站點上都找得到)要發掘sed的潛力則必須對正則表達式有足夠的理解正則表達式的資料可以看《Mastering Regular Expressions》作者Jeffrey Friedl(Oreilly
Unix系統所提供的手冊頁(man)也會有所幫助(試一下這些命令man sedman regexp或者看man ed中關於正則表達式的部分)但手冊提供的信息比較抽象——這也是它一直為人所诟病的不過它本來就不是用來教初學者如何使用sed或正則表達式的教材而只是為那些熟悉這些工具的人提供的一些文本參考

  括號語法前面的例子對sed命令基本上都使用單引號()而非雙引號()這是因為sed通常是在Unix平台上使用單引號下Unix的shell(命令解釋器)不會對美元符($)和後引號(``)進行解釋和執行而在雙引號下美元符會被展開為變量或參數的值後引號中的命令被執行並以輸出的結果代替後引號中的內容而在csh及其衍生的shell中使用感歎號(!)時需要在其前面加上轉義用的反斜槓(就像這樣\!)以保證上面所使用的例子能正常運行(包括使用單引號的情況下)DOS版本的Sed則一律使用雙引號()而不是引號來圈起命令
\t的用法為了使本文保持行文簡潔我們在腳本中使用\t來表示一個制表符但是現在大部分版本的sed還不能識別\t的簡寫方式因此當在命令行中為腳本輸入制表符時你應該直接按TAB鍵來輸入制表符而不是輸入\t下列的工具軟件都支持\t做為一個正則表達式的字元來表示制表符awkperlHHsedsedmod以及GNU sed v

  不同版本的SED不同的版本間的sed會有些不同之處可以想象它們之間在語法上會有差異具體而言它們中大部分不支持在編輯命令中間使用標簽(:name)或分支命令(bt)除非是放在那些的末尾這篇文檔中我們盡量選用了可移植性較高的語法以使大多數版本的sed的用戶都能使用這些腳本不過GNU版本的sed允許使用更簡潔的語法想像一下當讀者看到一個很長的命令時的心情
sed e /AAA/b e /BBB/b e /CCC/b e d
好消息是GNU sed能讓命令更緊湊
sed /AAA/b;/BBB/b;/CCC/b;d                                  # 甚至可以寫成
sed /AAA\|BBB\|CCC/b;d
此外請注意雖然許多版本的sed接受象/one/ s/RE/RE/這種在s前帶有空
格的命令但這些版本中有些卻不接受這樣的命令:/one/! s/RE/RE/這時
只需要把中間的空格去掉就行了

  速度優化當由於某種原因(比如輸入文件較大處理器或硬盤較慢等)需要提高

  命令執行速度時可以考慮在替換命令(s///)前面加上地址表達式來
提高速度舉例來說
sed s/foo/bar/g filename                                                    # 標准替換命令
sed /foo/ s/foo/bar/g filename                                          # 速度更快
sed /foo/ s//bar/g filename                                                # 簡寫形式
當只需要顯示文件的前面的部分或需要刪除後面的內容時可以在腳本中使用q
命令(退出命令)在處理大的文件時這會節省大量時間因此
sed n p filename                                                      # 顯示第
sed n q;p filename                                              # 一樣但快得多

  如果你有其他的單行腳本想與大家分享或者你發現了本文檔中錯誤的地方請發電子郵件給本文檔的作者(Eric Pement)郵件中請記得提供你所使用的sed版本該sed所運行的操作系統及對問題的適當描述本文所指的單行腳本指命令行的長度在個字符或個以下的sed腳本〔譯注

  譯注大部分情況下sed腳本無論多長都能寫成單行的形式(通過`e選項和`;號)——只要命令解釋器支持所以這裡說的單行腳本除了能寫成一行還對長度有所限制因為這些單行腳本的意義不在於它們是以單行的形式出現而是讓用戶能方便地在命令行中使用這些緊湊的腳本才是其意義所在


From:http://tw.wingwit.com/Article/program/qrs/201404/30412.html

    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.