SED?行?本快速?考(Unix 流??器) 2005年12月29日 英文??:USEFUL ONE-LINE SCRIPTS FOR SED (Unix stream editor) 原??:HANDY ONE-LINERS FOR SED (Unix stream editor) 整理:Eric Pement - ??:pemente[at]northpark[dot]edu 版本5.5 ?者:Joe Hong - ??:hq00e[at]126[dot]com 在以下地址可找到本文?的最新(英文)版本: http://sed.sourceforge.net/sed1line.txt http://www.pement.org/sed/sed1line.txt 其他?言版本: 中文 - http://sed.sourceforge.net/sed1line_zh-CN.html 捷克? - http://sed.sourceforge.net/sed1line_cz.html 荷? - http://sed.sourceforge.net/sed1line_nl.html 法? - http://sed.sourceforge.net/sed1line_fr.html 德? - http://sed.sourceforge.net/sed1line_de.html 葡? - http://sed.sourceforge.net/sed1line_pt-BR.html 文本?隔: -------- # 在每一行后面增加一空行 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/ *\(.\{6,\}\)\n/\1 /' # ?文件中的所有行??,但只?示非空白行的行?。 sed '/./=' filename | sed '/./N; s/\n/ /' # ?算行? (模? "wc -l") sed -n '$=' 文本??和替代: -------- # Unix?境:??DOS的新行符(CR/LF)?Unix格式。 sed 's/.$//' # 假?所有行以CR/LF?束 sed 's/^M$//' # 在bash/tcsh中,?按Ctrl-M改?按Ctrl-V sed 's/\x0D$//' # ssed、gsed 3.02.80,及更高版本 # Unix?境:??Unix的新行符(LF)?DOS格式。 sed "s/$/`echo -e \\\r`/" # 在ksh下所使用的命令 sed 's/$'"/`echo \\\r`/" # 在bash下所使用的命令 sed "s/$/`echo \\\r`/" # 在zsh下所使用的命令 sed 's/$/\r/' # gsed 3.02.80 及更高版本 # DOS?境:??Unix新行符(LF)?DOS格式。 sed "s/$//" # 方法 1 sed -n p # 方法 2 # DOS?境:??DOS新行符(CR/LF)?Unix格式。 # 下面的?本只?UnxUtils sed 4.0.7 及更高版本有效。要??UnxUtils版本的 # sed可以通?其特有的“--text”??。你可以使用?助??(“--help”)看 # 其中有?一?“--text”?以此?判?所使用的是否是UnxUtils版本。其它DOS # 版本的的sed??法?行?一??。但可以用“tr”????一??。 sed "s/\r//" infile >outfile # UnxUtils sed v4.0.7 或更高版本 tr -d \r outfile # GNU tr 1.22 或更高版本 # ?每一行前?的“空白字符”(空格,制表符)?除 # 使之左?? sed 's/^[ \t]*//' # ?本文末尾?于'\t'用法的描述 # ?每一行拖尾的“空白字符”(空格,制表符)?除 sed 's/[ \t]*$//' # ?本文末尾?于'\t'用法的描述 # ?每一行中的前?和拖尾的空白字符?除 sed 's/^[ \t]*//;s/[ \t]*$//' # 在每一行???插入5?空格(使全文向右移?5?字符的位置) sed 's/^/ /' # 以79?字符??度,?所有文本右?? sed -e :a -e 's/^.\{1,78\}$/ &/;ta' # 78?字符外加最后的一?空格 # 以79?字符??度,使所有文本居中。在方法1中,?了?文本居中每一行的前 # ?和后?都填充了空格。 在方法2中,在居中文本的?程中只在文本的前面填充 # 空格,并且最??些空格?有一半?被?除。此外每一行的后?并未填充空格。 sed -e :a -e 's/^.\{1,77\}$/ & /;ta' # 方法1 sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/' # 方法2 # 在每一行中查找字串“foo”,并?找到的“foo”替??“bar” sed 's/foo/bar/' # 只替?每一行中的第一?“foo”字串 sed 's/foo/bar/4' # 只替?每一行中的第四?“foo”字串 sed 's/foo/bar/g' # ?每一行中的所有“foo”都?成“bar” sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # 替?倒?第二?“foo” sed 's/\(.*\)foo/\1bar/' # 替?最后一?“foo” # 只在行中出?字串“baz”的情?下?“foo”替?成“bar” sed '/baz/s/foo/bar/g' # ?“foo”替?成“bar”,并且只在行中未出?字串“baz”的情?下替? sed '/baz/!s/foo/bar/g' # 不管是“scarlet”“ruby”?是“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 v1.5??文件中的空行?除 sed '1!G;h;$!d' # 方法1 sed -n '1!G;h;$p' # 方法2 # ?行中的字符逆序排列,第一?字成?最后一字,……(模?“rev”) sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//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' # ??字字串增加逗?分隔符?,?“1234567”改?“1,234,567” gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta' # GNU sed sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' # 其他sed # ??有小??和??的?值增加逗?分隔符(GNU sed) gsed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta' # 在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行) gsed '0~5G' # 只?GNU sed有效 sed 'n;n;n;n;G;' # 其他sed ??性地?示特定行: -------- # ?示文件中的前10行 (模?“head”的行?) sed 10q # ?示文件中的第一行 (模?“head -1”命令) sed q # ?示文件中的最后10行 (模?“tail”) sed -e :a -e '$q;N;11,$D;ba' # ?示文件中的最后2行(模?“tail -2”命令) sed '$!N;$!D' # ?示文件中的最后一行(模?“tail -1”) sed '$!d' # 方法1 sed -n '$p' # 方法2 # ?示文件中的倒?第二行 sed -e '$!{h;d;}' -e x # ?文件中只有一行?,?入空行 sed -e '1{$q;}' -e '$!{h;d;}' -e x # ?文件中只有一行?,?示?行 sed -e '1{$d;}' -e '$!{h;d;}' -e x # ?文件中只有一行?,不?出 # 只?示匹配正?表?式的行(模?“grep”) sed -n '/regexp/p' # 方法1 sed '/regexp/!d' # 方法2 # 只?示“不”匹配正?表?式的行(模?“grep -v”) sed -n '/regexp/!p' # 方法1,与前面的命令相?? sed '/regexp/d' # 方法2,?似的?法 # 查找“regexp”并?匹配行的上一行?示出?,但并不?示匹配行 sed -n '/regexp/{g;1!p;};h' # 查找“regexp”并?匹配行的下一行?示出?,但并不?示匹配行 sed -n '/regexp/{n;p;}' # ?示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所 # 在行的行? (?似“grep -A1 -B1”) sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h # ?示包含“AAA”、“BBB”或“CCC”的行(任意次序) sed '/AAA/!d; /BBB/!d; /CCC/!d' # 字串的次序不影??果 # ?示包含“AAA”、“BBB”和“CCC”的行(固定次序) sed '/AAA.*BBB.*CCC/!d' # ?示包含“AAA”“BBB”或“CCC”的行 (模?“egrep”) sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # 多?sed gsed '/AAA\|BBB\|CCC/!d' # ?GNU sed有效 # ?示包含“AAA”的段落 (段落?以空行分隔) # HHsed v1.5 必?在“x;”后加入“G;”,接下?的3??本都是?? sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;' # ?示包含“AAA”“BBB”和“CCC”三?字串的段落 (任意次序) sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d' # ?示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序) 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有效 # ?示包含65?或以上字符的行 sed -n '/^.\{65\}/p' # ?示包含65?以下字符的行 sed -n '/^.\{65\}/!p' # 方法1,与上面的?本相?? sed '/^.\{65\}/d' # 方法2,更?便一?的方法 # ?示部分文本——?包含正?表?式的行?始到最后一行?束 sed -n '/regexp/,$p' # ?示部分文本——指定行?范?(?第8至第12行,含8和12行) sed -n '8,12p' # 方法1 sed '8,12!d' # 方法2 # ?示第52行 sed -n '52p' # 方法1 sed '52!d' # 方法2 sed '52q;d' # 方法3, ?理大文件?更有效率 # ?第3行?始,每7行?示一次 gsed -n '3~7p' # 只?GNU sed有效 sed -n '3,${p;n;n;n;n;n;n;}' # 其他sed # ?示??正?表?式之?的文本(包含) sed -n '/Iowa/,/Montana/p' # ?分大小?方式 ??性地?除特定行: -------- # ?示通篇文?,除了??正?表?式之?的?容 sed '/Iowa/,/Montana/d' # ?除文件中相?的重复行(模?“uniq”) # 只保留重复行中的第一行,其他行?除 sed '$!N; /^\(.*\)\n\1$/!P; D' # ?除文件中的重复行,不管有?相?。注意hold space所能支持的?存 # 大小,或者使用GNU sed。 sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P' # ?除除重复行外的所有行(模?“uniq -d”) sed '$!N; s/^\(.*\)\n\1$/\1/; t; D' # ?除文件中??的10行 sed '1,10d' # ?除文件中的最后一行 sed '$d' # ?除文件中的最后?行 sed 'N;$!P;$!D;$d' # ?除文件中的最后10行 sed -e :a -e '$d;N;2,10ba' -e 'P;D' # 方法1 sed -n -e :a -e '1,10!{P;N;D;};N;ba' # 方法2 # ?除8的倍?行 gsed '0~8d' # 只?GNU sed有效 sed 'n;n;n;n;n;n;n;d;' # 其他sed # ?除匹配式?的行 sed '/pattern/d' # ?除含pattern的行。?然pattern # 可以?成任何有效的正?表?式 # ?除文件中的所有空行(与“grep '.' ”效果相同) sed '/^$/d' # 方法1 sed '/./!d' # 方法2 # 只保留多?相?空行的第一行。并且?除文件?部和尾部的空行。 # (模?“cat -s”) sed '/./,/^$/!d' #方法1,?除文件?部的空行,允?尾部保留一空行 sed '/^$/N;/\n$/D' #方法2,允??部保留一空行,尾部不留空行 # 只保留多?相?空行的前?行。 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 3.02.*有效 # ?除每?段落的最后一行 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中, 按 Ctrl-V 再按 Ctrl-H sed 's/.\x08//g' # sed 1.5,GNU sed,ssed所使用的十六?制的表示方法 # 提取新??或 e-mail 的?件? sed '/^$/q' # ?除第一行空行后的所有?容 # 提取新??或 e-mail 的正文部分 sed '1,/^$/d' # ?除第一行空行之前的所有?容 # ??件?提取“Subject”(???字段),并移除??的“Subject:”字? sed '/^Subject: */!d; s///;q' # ??件??得回复地址 sed '/^Reply-To:/q; /^From:/h; /./d;g;q' # ?取?件地址。在上一??本所?生的那一行?件?的基?上?一步的?非?? # 地址的部分剃除。(?上一?本) sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//' # 在每一行??加上一?尖括?和空格(引用信息) sed 's/^/> /' # ?每一行???的尖括?和空格?除(解除引用) sed 's/^> //' # 移除大部分的HTML??(包括跨行??) sed -e :a -e 's/<[^>]*>//g;/zipup.bat dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat 使用SED:Sed接受一?或多???命令,并且每?入一行后就依次?用?些命令。 ??入第一行?入后,sed?其?用所有的命令,然后??果?出。接?再?入第二 行?入,?其?用所有的命令……并重复???程。上一?例子中sed由?准?入? ?(即命令解?器,通常是以管道?入的形式)?得?入。在命令行?出一?或多 ?文件名作????,?些文件取代?准?入??成?sed的?入。sed的?出?被 送到?准?出(?示器)。因此: cat filename | sed '10q' # 使用管道?入 sed '10q' filename # 同?效果,但不使用管道?入 sed '10q' filename > newfile # ??出?移(重定向)到磁?上 要了解sed命令的使用?明,包括如何通??本文件(而非?命令行)?使用?些命 令,???《sed & awk》第二版,作者Dale Dougherty和Arnold Robbins (O'Reilly,1997;http://www.ora.com),《UNIX Text Processing》,作者 Dale Dougherty和Tim O'Reilly(Hayden Books,1987)或者是Mike Arst?的教 程——??包的名?是“U-SEDIT2.ZIP”(在?多站?上都找得到)。要?掘sed 的?力,?必??“正?表?式”有足?的理解。正?表?式的?料可以看 《Mastering Regular Expressions》作者Jeffrey Friedl(O'reilly 1997)。 Unix系?所提供的手??(“man”)也?有所?助(?一下?些命令 “man sed”、“man regexp”,或者看“man ed”中?于正?表?式的部分),但 手?提供的信息比?“抽象”——?也是它一直?人所?病的。不?,它本?就不 是用?教初?者如何使用sed或正?表?式的教材,而只是?那些熟悉?些工具的人 提供的一些文本?考。 括??法:前面的例子?sed命令基本上都使用?引?('...')而非?引? ("...")?是因?sed通常是在Unix平台上使用。?引?下,Unix的shell(命令 解?器)不??美元符($)和后引?(`...`)?行解?和?行。而在?引?下 美元符?被展???量或??的值,后引?中的命令被?行并以?出的?果代替 后引?中的?容。而在“csh”及其衍生的shell中使用感??(!)?需要在其前 面加上??用的反斜杠(就像??:\!)以保?上面所使用的例子能正常?行 (包括使用?引?的情?下)。DOS版本的Sed?一律使用?引?("...")而不是 引??圈起命令。 '\t'的用法:?了使本文保持行文?洁,我?在?本中使用'\t'?表示一?制表 符。但是?在大部分版本的sed?不能??'\t'的??方式,因此?在命令行中? ?本?入制表符?,你??直接按TAB???入制表符而不是?入'\t'。下列的工 具?件都支持'\t'做?一?正?表?式的字元?表示制表符:awk、perl、HHsed、 sedmod以及GNU sed v3.02.80。 不同版本的SED:不同的版本?的sed?有些不同之?,可以想象它?之?在?法上 ?有差异。具体而言,它?中大部分不支持在??命令中?使用??(:name)或分 支命令(b,t),除非是放在那些的末尾。?篇文?中我??量?用了可移植性?高 的?法,以使大多?版本的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/RE1/RE2/”?种在's'前?有空 格的命令,但?些版本中有些?不接受??的命令:“/one/! s/RE1/RE2/”。?? 只需要把中?的空格去掉就行了。 速度优化:?由于某种原因(比如?入文件?大、?理器或硬??慢等)需要提高 命令?行速度?,可以考?在替?命令(“s/.../.../”)前面加上地址表?式? 提高速度。?例??: sed 's/foo/bar/g' filename # ?准替?命令 sed '/foo/ s/foo/bar/g' filename # 速度更快 sed '/foo/ s//bar/g' filename # ??形式 ?只需要?示文件的前面的部分或需要?除后面的?容?,可以在?本中使用“q” 命令(退出命令)。在?理大的文件?,???省大量??。因此: sed -n '45,50p' filename # ?示第45到50行 sed -n '51q;45,50p' filename # 一?,但快得多 如果你有其他的?行?本想与大家分享或者你??了本文?中??的地方,??? 子?件?本文?的作者(Eric Pement)。?件中??得提供你所使用的sed版本、 ?sed所?行的操作系?及???的适?描述。本文所指的?行?本指命令行的? 度在65?字符或65?以下的sed?本〔?注1〕。本文?的各种?本是由以下所列作 者所?或提供: Al Aab # 建立了“seders”?件列表 Edgar Allen # ?多方面 Yiorgos Adamopoulos # ?多方面 Dale Dougherty # 《sed & awk》作者 Carlos Duarte # 《do it with sed》作者 Eric Pement # 本文?的作者 Ken Pizzini # GNU sed v3.02 的作者 S.G. Ravenhall # 去html???本 Greg Ubben # 有?多??并提供了?多?助 ------------------------------------------------------------------------- ?注1:大部分情?下,sed?本??多?都能?成?行的形式(通?`-e'??和`;' ?)——只要命令解?器支持,所以?里?的?行?本除了能?成一行???度有 所限制。因??些?行?本的意?不在于它?是以?行的形式出?。而是?用?能 方便地在命令行中使用?些??的?本才是其意?所在。 Valid XHTML 1.0 Strict 我想以上的式子都看的懂,應該sed就算很了解了吧 另外SED 通常我門都用 '/ ' 當分隔線 但是我們可以用其他符號當分隔線,你知道嗎? 有時候會發現這種功能還蠻好用的 當分隔字元在替換命令中的時候 或是為了讓式子更容易看的懂 便可以使用其他的字元替換 比如說: sed 's$/$$g' sed 'sA/AAg' 這兩種奇怪的寫法 都是可以work的 這個跟sed 's/\///g' 是依樣的意思 在sed中 有時候我們會想用到'+'的正規表示式 (表示一個以上的字元) 但是無法像*或?一樣直接使用 除了我們可以用 \{1,\}之外 在bash中 我也可以用 '\+' 取代 無意中發現將+號跳脫就可了