sed的一篇強(qiáng)例子集錦的翻譯
翻譯了一下
http://bbs.chinaunix.net/forum/24/20040514/325187.html我是新手,翻譯得不好,加注得馬馬虎虎,很多地方都是憑自己的理解寫的。由于剛開始學(xué)sed,所以很多地方寫得很初級(jí),呵呵,難免有些羅嗦。寫到最后又有些頭暈,還請(qǐng)大蝦們多多指點(diǎn),里頭好幾個(gè)命令我解釋不清楚,如不吝賜教,感激不盡!
FILE SPACING:
# double space a file
#使一個(gè)文件中每一行都占用兩行空間(就是在每一行后邊插一行空行)
sed G
###sed 中G命令的解釋為append hold space to pattern space.
###就是在當(dāng)前位置后加一行保留空間中的內(nèi)容,無任何動(dòng)作時(shí),保留空間為空行
###所以就double space a file 了,呵呵.
# double space a file which already has blank lines in it. Output file
# should contain no more than one blank line between lines of text.
#假若文件已經(jīng)含有空白行在其中,使一個(gè)文件中每一行占用兩行
#空間。輸出文件中文本行之間不含有超過一行的空行
sed '/^$/d;G'
###先用sed '/^$/d' 查找并刪除空行;然后用 sed G插入空行
# triple space a file
#使一個(gè)文件中每一行都占用三行空間(就是在每一行后邊插兩行空行)
sed 'G;G'
###不用說了吧,重復(fù)兩次sed G.
# undo double-spacing (assumes even-numbered lines are always blank)
#撤銷占用兩行空間的%作(假設(shè)偶數(shù)行都是空白行)
sed 'n;d'
###sed 中命令n的解釋為Read the next line of input into the pattern space.
###所以我理解為用sed n 讀入下一行兵緊接著用sed d 刪除,如果隔兩行刪除一行那么
###用sed 'n,n,d',要是隔100行刪除一行呢....什么???!!!你要寫100個(gè)n???!!!
# insert a blank line above every line which matches "regex"
#在每個(gè)含有字符串regex的行上插入一行空白行
sed '/regex/{x;p;x;}'
###sed 中命令x解釋為Exchange the contents of the hold and pattern spaces.
###我的理解也就是交換保留空間與模式空間的內(nèi)容
###sed 中命令p為Print the current pattern space.就是打印模式空間中的內(nèi)容.
###所以理解為保留空間中開始為空行,模式空間中經(jīng)過sed '/regex/'查詢后為包含
###regex內(nèi)容的那一行,1)x;交換模式空間和保留空間的內(nèi)容,此時(shí)模式空間中內(nèi)容
###為空行,保留空間中內(nèi)容為含有regex內(nèi)容的行, 2)p;命令打印模式空間內(nèi)容(
###空行),在原文中含有regex內(nèi)容的那一行的位置出現(xiàn)兩行空行,其中后一行為
###模式空間中的內(nèi)容,3)x;后交換模式空間和保留空間中的內(nèi)容,....結(jié)果就是在原
###來出現(xiàn)regex的位置前一行加入了一行空行。
# insert a blank line below every line which matches "regex"
# 在每個(gè)含有字符串regex的行下插入一行空白行
sed '/regex/G'
###比較簡(jiǎn)單,查找后在后邊加入一空行
# insert a blank line above and below every line which matches "regex"
#在每個(gè)含有字符串regex的行上,下各插入一行空白行
sed '/regex/{x;p;x;G;}'
###兄弟兩個(gè)sed '/regex/G'和sed '/regex/{x;p;x;}'合作的結(jié)果.
NUMBERING:
# number each line of a file (simple left alignment) Using a tab (see
# note on '\t' at end of file)instead of space will preserve margins.
#給文件每一行加上數(shù)字序號(hào)。用TAB制表符替換空間來保留空白(?)
#(在數(shù)字序號(hào)和文本中間加一TAB制表符)
sed = filename | sed 'N;s/
/\t/'
###sed = filename的功能是 Print the current line number.
###但是這個(gè)功能是在每一行前面另加一行,并且顯示行號(hào),而不是直接在行首加序號(hào)
###sed中命令N的解釋為Append the next line of input into the pattern space.
###也就是把當(dāng)前行后一行的內(nèi)容加在當(dāng)前行后邊.
###sed中命令s/regexp/replacement/解釋為Attempt to match regexp against the
###pattern space. If successful, replace that portion matched with
### replacement.大概意思是在模式空間外匹配regexp,如果成功,使用匹配replace
###ment的內(nèi)容替換regexp.說白了就是查找替換吧.
是換行符,\t是TAB制表符,
###所以整個(gè)命令的意思也就出來了.
# number each line of a file (nnumber on left, right-aligned)
#給文件每一行加上數(shù)字序號(hào)(數(shù)字在左邊,向右對(duì)齊?)
sed = filename | sed 'N; s/^/ /; s/ *\(.\{6,\}\)
/\1 /'
### 前面不用說了,但是后邊......
###s/ *\(.\{6,\}\)
/\1 /' 這個(gè)地方確實(shí)不是很明白!~~
# number each line of file, but only print numbers if line is not blank
#給文件每一行加上數(shù)字序號(hào),但是僅當(dāng)行非空時(shí)打印數(shù)字
sed '/./=' filename | sed '/./N; s/
/ /'
###sed '/./=' filename的用處是查找除非空行賦予行號(hào),sed '/./N; s/
/ /'查找非
##空行并把后一行附加到當(dāng)前行,然后用空格替換換行符
# count lines (emulates "wc -l")
#統(tǒng)計(jì)行數(shù)(類似于 "wc -l")
sed -n '$='
#sed中參數(shù)n的含義是suppress automatic printing of pattern space,也就是限制
###自動(dòng)打印模式空間中內(nèi)容的功能, '$='中$的含義是Match the last line,=前邊
###已經(jīng)說過了,就是打印行號(hào),所以匹配最后一行而且只打印行號(hào)不打印內(nèi)容,就是
###"wc -l"了
TEXT CONVERSION AND SUBSTITUTION:
# IN UNIX ENVIRONMENT: convert DOS newlines (cR/LF)to Unix format
#在UNIX環(huán)境下:轉(zhuǎn)換DOS換行符(?)(cR/LF)UNIX格式
sed 's/.$//' # assumes that all lines end with CR/LF
# 假設(shè)所有的行都以CR/LF結(jié)尾
###可能在DOS中的ASCII碼(包括CR/LF)到了UNIX中都成了單字符吧,又因?yàn)?.$"代表
###每行最后一個(gè)字符,所以把它們替換掉就OK了.CR/LF是啥?CR---ASCII Carriage
###Return(ASCII 回車) ,LF----ASCII Linefeed (ASCII換行)
sed 's/^M$//' # in bash/tcsh, press Ctrl-V then Ctrl-M
#在bash/tcsh中,按下Ctrl-V然后按 Ctrl-M
###沒啥說的,就是查找替換,注意命令中"^M"在輸入時(shí)一定是按下Ctrl-V然后按 Ctrl-M
###如果輸入成ctrl+6鍵,然后輸入一個(gè)大寫M,什么替換也完成不了啦.
sed 's/\x0D$//' # gsed 3.02.80, but top script is easier
# ???
###不是很了解!高手說一下吧!
# IN UNIX ENVIRONMENT: convert Unix newlines (F)to DOS format
#在unix環(huán)境中:轉(zhuǎn)換Unix換行符(F)DOS格式
sed "s/$/`echo -e \\\r`/" # command line under ksh
#在ksh下的命令行
sed 's/$'"/`echo \\\r`/" # command line under bash
#在bash下的命令行
sed "s/$/`echo \\\r`/" # command line under zsh
#在zsh下的命令行
sed 's/$/\r/' # gsed 3.02.80
# gsed3.02.80版本下的命令行
###以上四個(gè)命令是在不同的shell版本下用\r(好象就是ASCII碼下的CR)替換行尾
# IN DOS ENVIRONMENT: convert Unix newlines (F)to DOS format
#在DOS環(huán)境下轉(zhuǎn)換Unix換行符到DOS格式
sed "s/$//" # method 1
sed -n p # method 2
###這句又不是很了解,本來$就是行尾了,把行尾替換成空,那就變成了DOS格式了嗎?
###下邊一句也很奇怪,參數(shù)-n是suppress automatic printing of pattern space,命
###令p是Print the current pattern space,一正一反就換成DOS格式了?乖乖~~
# IN DOS ENVIRONMENT: convert DOS newlines (cR/LF)to Unix format
#在Dos環(huán)境下:轉(zhuǎn)換DOS換行符為UNIX格式
# Cannot be done with DOS versions of sed. Use "tr" instead.
#用DOS版本的sed不能做到這點(diǎn),用"tr"代替.
tr -d \r outfile # GNU tr version 1.22 or higher
#GNU tr 1.22版本或者更高版本
# delete leading whitespace (spaces, tabs)from front of each line
# aligns all text flush left
#刪除每一行開頭的空白(空格,TAB)左對(duì)齊排列全文.
sed 's/^[ \t]*//' # see note on '\t' at end of file
# ???
### 又是替換成空,^[ \t]* 的含義為以空格或者TAB鍵開始的(或者是他們的組合)行.
# delete trailing whitespace (spaces, tabs)from end of each line
#從每一行結(jié)尾處刪除最后的空格(空格,TAB)
sed 's/[ \t]*$//' # see note on '\t' at end of file
#??
### 跟上邊的命令"前呼后擁"呀.
# delete BOTH leading and trailing whitespace from each line
#刪除每一行的開頭和結(jié)尾的空格
sed 's/^[ \t]*//;s/[ \t]*$//'
###兩步走.
# insert 5 blank spaces at beginning of each line (ake page offset)
#在每一行開始處插入5個(gè)空格(整頁偏移)
sed 's/^/ /'
###沒啥說的.
# align all text flush right on a 79-column width
#右對(duì)齊,按79列寬排列所有文本
sed -e :a -e 's/^.\{1,78\}$/ &/;ta' # set at 78 plus 1 space
###這個(gè)語句好像很麻煩,不過看懂了還挺有意思.:)
###首先出現(xiàn)了幾個(gè)新東東1.":" 2."&". 3. "-e " 4."t",解釋一下
###1.":" Label for b and t commands.(給b和t命令加注標(biāo)簽)
###2."&" 表示重復(fù)整個(gè)匹配的規(guī)則表達(dá)式.
###3. "-e" add the script to the commands to be executed
### 把腳本加到命令里用以執(zhí)行
###4. t label If a s/// has done a successful substitution since the last
###input line was read and since the last t or T command, then branch to
###label; if label is omitted, branch to end of script.
###如果從讀入最后一個(gè)輸入行并且執(zhí)行最后一個(gè)t或者T命令后,一個(gè)s///命令成功替換,
###那么流程分支指向label處,如果label被忽略(就是沒有成功替換吧,我想),那么流程
###分支指向腳本結(jié)束.
###回過頭來看,整個(gè)sed命令行是一個(gè)循環(huán)執(zhí)行的語句,每一行都要替換(78-當(dāng)前行的字
###符數(shù))次,所以如果整個(gè)文件比較大,或者一行字符數(shù)比較少,做這個(gè)動(dòng)作就有點(diǎn)吃力了.
###不信你試試吧,呵呵.
# center all text in the middle of 79-column width. In method 1,
# spaces at the beginning of the line are significant, and trailing
# spaces are appended at the end of the line. In method 2, spaces at
# the beginning of the line are discarded in centering the line, and
# no trailing spaces appear at the end of lines.
#使所有文本居于79列寬的格式中央。在第一種方法中,每一行開頭處的空格是
#很重要的,最后的空格被附在行尾。第二種方法中,一行開頭的空格在中心對(duì)
#齊的行中被丟棄,行尾也沒有原來結(jié)尾處的空格。
sed -e :a -e 's/^.\{1,77\}$/ & /;ta' # method 1
sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\(*\)1/\1/' # method 2
###跟上邊的差不多,當(dāng)兩邊都加空格的時(shí)候,效率要高一些~~
# substitute (ind and replace)"foo" with "bar" on each line
#在每一行中用"bar"替換(找并替換)foo"
sed 's/foo/bar/' # replaces only 1st instance in a line
# 在一行中,僅在第一次出現(xiàn)時(shí)替換
sed 's/foo/bar/4' # replaces only 4th instance in a line
#在一行中,僅在第四次出現(xiàn)時(shí)替換
sed 's/foo/bar/g' # replaces ALL instances in a line
#在一行中替換所有出現(xiàn)的值
###這三個(gè)命令很簡(jiǎn)單,不多說了.
sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # replace the next-to-last case
#替換緊鄰最后一個(gè)匹配出現(xiàn)的值
###'s///---- The replacement may contain the special character & to refer to that
###portion of the pattern space which matched, and the special escapes \1
### through \9 to refer to the corresponding matching sub-expressions in the regexp.
###就不直接翻譯了,大概意思就是replacement處可以包含&代表匹配的模式空間中
###的部分,特殊的\1-\9可以代表regexp中相應(yīng)的"子表達(dá)式",也就是說前面regexp
###可以分為幾個(gè)子表達(dá)式,而后邊replacement中可以用\1-\9分別代表它們.這樣就
###增加了靈活性,便于修改sed命令.
###把regexp中的\去掉后,就變成(.*)foo(*foo),其中(.*)表示零個(gè)或者多個(gè)字符,
###這樣加上后邊的\1bar\2就變成了改變倒數(shù)第二個(gè)foo,而倒數(shù)第一個(gè)不變
sed 's/\(*\)foo/\1bar/' # replace only the last case
#只替換最后一個(gè)值
###比上一個(gè)簡(jiǎn)單
# substitute "foo" with "bar" ONLY for lines which contain "baz"
#在每一含有"baz"的行中用"bar"替換(查找并替換)foo"
sed '/baz/s/foo/bar/g'
### /baz/用來查找,后邊的用來替換
# substitute "foo" with "bar" EXCEPT for lines which contain "baz"
#在每一不含有"baz"的行中用"bar"替換(找并替換)foo"
sed '/baz/!s/foo/bar/g'
###反其道而行之.
# change "scarlet" or "ruby" or "puce" to "red"
#將"scarlet"或者"ruby"或者"puce"替換成"red"
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' # most seds
#大多數(shù)sed可用
###三步走.
gsed 's/scarlet\|ruby\|puce/red/g' # GNU sed only
#僅GNU sed可用
# reverse order of lines (emulates "tac")
#反轉(zhuǎn)文章行的順序(類似"tac" )
# bug/feature in HHsed v1.5 causes blank lines to be deleted
#???????
sed '1!G;h;$!d' # method 1
###
###首先看第一個(gè)命令1!G,這個(gè)是啥意思?"!"表示后邊的命令對(duì)所有沒有
###被選定的行發(fā)生作用,G呢?獲得保留空間(專業(yè)名詞叫內(nèi)存緩沖區(qū)?)中
###的內(nèi)容,并追加到當(dāng)前模式空間的后面.1就是選定第一行.h的含義是拷貝
###模式空間內(nèi)容到保留空間(內(nèi)存緩沖區(qū))。那么先看 sed '1!G'什么含義
###執(zhí)行一下這個(gè)命令,假若文件是
### $ cat test.txt
### 1
### 2
### 3
### 4
###那么 sed '1!G' test.txt的結(jié)果是
### $ sed '1!G' test.txt
### 1
### 2
###
### 3
###
### 4
###
### $
### 也就是說除了第一行,后邊每行都加了空行,這是因?yàn)閮?nèi)存緩沖區(qū)中默認(rèn)值
###是空行吧。然后我們加上h,看看發(fā)生什么
### $ sed '1!G;h' test.txt
### 1
### 2
### 1
### 3
### 2
### 1
### 4
### 3
### 2
### 1
### $
### 空行沒了,咋回事?我是這樣理解的,不知道對(duì)不對(duì),大家?guī)椭纯矗海?
###首先要確定,執(zhí)行到每一行,sed把當(dāng)前處理的行存在臨時(shí)的緩沖區(qū)內(nèi),
###稱為模式空間(pattern space).一旦sed完成對(duì)模式空間中行的處理,模式
###空間中的行就被送往屏幕.行被處理完成后,就被移出模式空間...
###
###命令執(zhí)行第一行時(shí),由于匹配了第一行,所以"!G"不起作用,只打印了
###第一行的內(nèi)容,然后"h"把模版塊中的內(nèi)容也就是第一行的內(nèi)容拷貝進(jìn)緩沖區(qū),
###注意此時(shí)是用第一行的內(nèi)容替換空行.模式空間中的內(nèi)容要打印,所以出現(xiàn)1.
###執(zhí)行到第二行時(shí),打印第二行內(nèi)容,而且由于不匹配"1",所以在后邊"G"命令起
###作用,獲得了緩沖區(qū)中的第一行的內(nèi)容,然后加到當(dāng)前模式空間中,并打印,出現(xiàn)
###21。然后把模式空間中的內(nèi)容寫入緩沖區(qū),也就是把21寫入緩沖區(qū)。執(zhí)行到第三行
###匹配不成功,所以緩沖區(qū)的內(nèi)容應(yīng)該是第二行的內(nèi)容加上第一行的內(nèi)容,追加到模
###式空間的第三行后邊:321.然后把321拷貝到緩沖區(qū),...以此類推就出現(xiàn)了上
###面的結(jié)果.
###我不知道這么解釋對(duì)不對(duì),但是當(dāng)我把命令中的1換成2,3,4后執(zhí)行,得到了我
###想象的結(jié)果。還請(qǐng)高手指點(diǎn)~~
###加上最后一句"$!d",那就是前面三行的結(jié)果刪除,保留最后一行。這樣就形成了
### tac的效果啦。
sed -n '1!G;h;$p' # method 2
###與上邊類似的,不羅嗦!
# reverse each character on the line (emulates "rev")
#反轉(zhuǎn)一行中每個(gè)字符的順序(類似"rev")
sed '/
/!G;s/\(.\)\(.*
\)/&\2\1/;//D;s/.//'
###這個(gè)命令真是.....
###我是在解釋不通,所以按照我的想法來說一下吧,完全是瞎說!
###'/
/!G'是判斷本行是否有換行符,如果沒有執(zhí)行G命令
###'s/\(.\)\(.*
\)/&\2\1/'命令是在原來行+第二個(gè)字符(或者沒有)開始到換行符+第一個(gè)字符
###//D命令是在模式空間刪除第一行,注意執(zhí)行完成后如果模式空間不為空,繼續(xù)下一個(gè)
###循環(huán)執(zhí)行.
###s/.//命令是刪除第一個(gè)字符
###假設(shè)一行文字是 123
###那么執(zhí)行后模式空間中的內(nèi)容應(yīng)該按下邊的順序變化
### 123
### 123
23
1
### 23
1
### 23
13
21
### 13
21
### 3
21
### 3
21
321
###
321
### 321
### 我的疑問就是,為什么第一次沒有執(zhí)行s/.//?!如果執(zhí)行了,那么就得不到結(jié)果了啊!
### 救~~~~命~~~啊!????????????????????????????????
# join pairs of lines side-by-side (like "paste")
#把兩行合為一行(類似于"paste")
sed '$!N;s/
/ /'
###這個(gè)命令改成 sed 'N;s/
/ /'一樣可以達(dá)到目的,不知前面
###的$!有什么用處...
# if a line ends with a backslash, append the next line to it
#如果一行以"\"結(jié)束,把下一行加在此行上
sed -e :a -e '/\\$/N; s/\\
//; ta'
###循環(huán)%作,兩次替換。
# if a line begins with an equal sign, append it to the previous line
# and replace the "=" with a single space
#如果一等號(hào)開始某一行,把這一行加到前一行后邊,并且用一個(gè)空格替換等號(hào)
sed -e :a -e '$!N;s/
=/ /;ta' -e 'P;D'
###和上邊差不多,要注意兩個(gè)新的命令:
### P命令--Print up to the first embedded newline of the current
###pattern space.打印當(dāng)前模式空間中第一行。
###D命令--Delete up to the first embedded newline in
### the pattern space. Start next cycle, but skip reading from
###the input if there is still data in the pattern space.
###刪除當(dāng)前模式空間中第一行。開始新的循環(huán),但是如果在模式空間中仍然
###有數(shù)據(jù),那么跳過讀取輸入。
# add commas to numeric strings, changing "1234567" to "1,234,567"
#給數(shù)字串加逗號(hào),把"1234567"變?yōu)?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' # other seds
###(.*[0-9])表示零個(gè)或者多個(gè)字符(可能包含數(shù)字)+一個(gè)數(shù)字,而
###([0-9]{3})表示三個(gè)數(shù)字,然后不停的替換,直到條件不成立,也就是沒有
###四個(gè)以上連續(xù)的數(shù)字出現(xiàn)就停止了.
# add commas to numbers with decimal points and minus signs (NU sed)
#給帶有小數(shù)點(diǎn)和負(fù)號(hào)的數(shù)字的數(shù)字加上逗號(hào)
gsed ':a;s/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g;ta'
###沒有g(shù)sed,不解釋了
# add a blank line every 5 lines (after lines 5, 10, 15, 20, etc.)
#每五行后加一空行
gsed '0~5G' # GNU sed only
sed 'n;n;n;n;G;' # other seds
###一大早就說過了的...
SELECTIVE PRINTING OF CERTAIN LINES:
# print first 10 lines of file (emulates behavior of "head")
#打印一個(gè)文件的前10行(模仿動(dòng)作"head")
sed 10q
# print first line of file (emulates "head -1")
#打印一個(gè)文件的第一行(仿"head -1")
sed q
### q命令的解釋Immediately quit the sed script without processing
###any more input, except that if auto-print is not disabled the
###current pattern space will be printed.
### 所以上邊兩個(gè)命令都清楚了,執(zhí)行到第10行退出就打印前10行,執(zhí)行第一行
###就退出就打印第一行
# print the last 10 lines of a file (emulates "tail")
#打印一個(gè)文件的后10行(仿"tail")
sed -e :a -e '$q;N;11,$D;ba'
###Label b : Branch to label; if label is omitted, branch to end of script.
###命令D 刪除模式空間內(nèi)第一個(gè) newline 字母
前的資料。
###命令N 把輸入的下一行添加到模式空間中。
### b label:分支到腳本中帶有標(biāo)號(hào)的地方,如果標(biāo)號(hào)不存就分支到腳本的末尾
###
waker 寫到:
試著注一下,不知道對(duì)不對(duì)
如果我們只看sed -e :a -e '$q;N;ba'
這個(gè)循環(huán)不停的讀入下 一行直到結(jié)尾,這樣整個(gè)文本就形成一個(gè)由
分割的鏈
現(xiàn)在加上11,$D
sed -e :a -e '$q;N;11,$D;ba'
如果文本不超過10行
模式空間將保留整個(gè)文本打印出來
如果文本大于10行
從第11行開始,在下一行加入到鏈中后,模式空間第一個(gè)由
分割的記錄將被刪除,這樣看起來就是鏈頭被鏈尾擠出整個(gè)鏈,總是保持10個(gè)鏈環(huán),循環(huán)結(jié)束后,鏈中保存的就是文件的后10行,最后印出結(jié)果
# print the last 2 lines of a file (emulates "tail -2")
#打印一個(gè)文件的最后兩行(仿"tail -2")
sed '$!N;$!D'
### 開始看不太懂,抄了CU精華一段
###sed '$!N;$!D' : 對(duì)文件倒數(shù)第二行以前的行來說,N 將當(dāng)前行的下一行放到模
###式空間中以后,D 就將模式空間的內(nèi)容刪除了;到倒數(shù)第二行的時(shí)候,將最后一行
###附加到倒數(shù)第二行下面,然后最后一行不執(zhí)行 D ,所以文件的最后兩行都保存下來了。
###不知道是這段話說得有些含糊,還是我理解得有偏差,總覺得D命令解釋成
###"將模式空間的內(nèi)容刪除了"有些讓人糊涂.
###而我是這樣理解的,不知道對(duì)不對(duì).首先說D命令是 Delete up to the first
###embedded newline in the pattern space.也就是說D命令是刪除模式空間中
###第一個(gè)換行符之前的內(nèi)容,也就是刪除第一行.然后D命令的解釋還有一句,我認(rèn)為
###這句很重要: Start next cycle, but skip reading from the input if there
### is still data in the pattern space.開始下一個(gè)循環(huán),但是如果模式空間中有
###數(shù)據(jù),則跳過從輸入中讀取數(shù)據(jù).
###具體怎么工作呢? 假設(shè)文件為
### $ cat test.txt
### 1
### 2
### 3
### 4
### 5
### 那么當(dāng)執(zhí)行第一行時(shí),$!N把第二行加入到模式空間中第一行后邊,然后$!D把第一行
###內(nèi)容刪除,模式空間中只剩下第二行的內(nèi)容.注意,此時(shí)由于D命令開始下一個(gè)循環(huán),
###所以不打印模式空間中的內(nèi)容! (這個(gè)地方也是我想了半天才這么解釋的,我也知道
###很可能不對(duì),歡迎拍磚,呵呵)由于D命令要求模式空間中有數(shù)據(jù)的話就跳過讀取下一行,
###所以繼續(xù)下一個(gè)循環(huán)又到了$!N,此時(shí)讀入第三行加到第二行后邊,....以此類推。
###執(zhí)行到讀入第5行附加在第四行后邊,然后由于$!D得不到執(zhí)行,所以第4行和第5行
###都被保留,命令結(jié)束,打印模式空間...
# print the last line of a file (emulates "tail -1")
#打印一個(gè)文件的最后一行(仿"tail -1")
sed '$!d' # method 1
sed -n '$p' # method 2
###哈哈,終于看懂了一個(gè),你也看懂了吧 :)
# print only lines which match regular expression (emulates "grep")
#只打印匹配的一定字符的行(仿"grep")
sed -n '/regexp/p' # method 1
sed '/regexp/!d' # method 2
###明白參數(shù)-n和命令p和d就明白這兩個(gè)命令.
# print only lines which do NOT match regexp (emulates "grep -v")
#只打印于一定字符不匹配的行(效"grep -v")
sed -n '/regexp/!p' # method 1, corresponds to above
sed '/regexp/d' # method 2, simpler syntax
###和上邊相反,正如注釋所說.
# print the line immediately before a regexp, but not the line
# containing the regexp
#打印包含"regexp"那一行的上一行,但是不打印包含"regexp"的行.
sed -n '/regexp/{g;1!p;};h'
###在命令執(zhí)行到包含"regexp"那一行的上一行時(shí),模式空間中這行的內(nèi)容被
###拷貝到保留空間中.執(zhí)行到包含"regexp"那一行時(shí)就打印它了.
# print the line immediately after a regexp, but not the line
# containing the regexp
#打印在"regexp"之后緊跟那一行,但是除去包含"regexp"的行.
sed -n '/regexp/{n;p;}'
###與上邊類似,比上邊簡(jiǎn)單.
# print 1 line of context before and after regexp, with line number
# indicating where the regexp occurred (imilar to "grep -A1 -B1")
#在"regexp"前后打印一行上下文,使其行號(hào)指示"regexp"在哪里出現(xiàn)(
#grep -A1 -B1相似)
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
###看上去好像挺復(fù)雜,其實(shí)倒是不難解釋.
###假設(shè)文檔是這樣
###$ cat test.txt
### 1 abc
### 2 cde
### 3 regexp
### 4 fgh
### 5 xyz
###命令執(zhí)行到regexp前一行,引號(hào)里邊的命令不執(zhí)行,只執(zhí)行h命令得到結(jié)果
### command parttern space holdspace output
### 執(zhí)行到前一行 2cde 2cde
### 執(zhí)行到regexp行 "=" 3regexp 3
### "x" 2cde 3regexp
### "1!p" 2cde 3regexp 2cde
### "g" 3regexp 3regexp
### "$N" 3regexp 4fgh 3regexp
### "p" 3regexp 4fgh 3regexp 3regexp
### 4fgh
### "D" 4fgh 3regexp
### "h" 4fgh 4fgh
###
### 看一下最右邊的輸出結(jié)果,還不錯(cuò)吧!
# grep for AAA and BBB and CCC (n any order)
#查找"AAA"和"BBB"和"CCC".(任意順序)
sed '/AAA/!d; /BBB/!d; /CCC/!d'
# grep for AAA and BBB and CCC (n that order)
# 查找"AAA"和"BBB"和"CCC".(一定順序)
sed '/AAA.*BBB.*CCC/!d'
# grep for AAA or BBB or CCC (emulates "egrep")
#查找"AAA"或"BBB"或"CCC".(任意順序)
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # most seds
gsed '/AAA\|BBB\|CCC/!d' # GNU sed only
###上邊三個(gè)沒什么說的,就是查找功能唄.
# print paragraph if it contains AAA (blank lines separate paragraphs)
# HHsed v1.5 must insert a 'G;' after 'x;' in the next 3 scripts below
#如果某段包含"AAA",則打印這一段。(空行用來分隔段落)
#HHsed v1.5必須在'x;'之后插入一個(gè)'G;'
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'
###前邊一部分命令用保留空間來存儲(chǔ)整個(gè)段落內(nèi)容,后邊一個(gè)命令用來查找
# print paragraph if it contains AAA and BBB and CCC (n any order)
#如果某段包含"AAA"和"BBB"和"CCC",則打印這一段
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
###同上
# print paragraph if it contains AAA or BBB or CCC
# 如果某段包含"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 only
###同上
# print only lines of 65 characters or longer
#僅打印長(zhǎng)于65個(gè)字符的行
sed -n '/^.\{65\}/p'
###這也沒什么好說的,正則表達(dá)式的運(yùn)用.
# print only lines of less than 65 characters
#僅打印少于65個(gè)字符的行
sed -n '/^.\{65\}/!p' # method 1, corresponds to above
sed '/^.\{65\}/d' # method 2, simpler syntax
###又沒啥吧
# print section of file from regular expression to end of file
#打印從字符"regexp"開始到文件結(jié)束的部分
sed -n '/regexp/,$p'
###還沒啥,注意","的作用是選擇行的范圍,從包含regexp的行到最后一行
# print section of file based on line numbers (ines 8-12, inclusive)
#根據(jù)行號(hào)來打印文件的一部分(-12行,包括在內(nèi))
sed -n '8,12p' # method 1
sed '8,12!d' # method 2
# print line number 52
#打印第52行
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3, efficient on large files
###僅注意第三種方法效率比較高就行了
# beginning at line 3, print every 7th line
#從第三行開始,每7行打印一行
gsed -n '3~7p' # GNU sed only
sed -n '3,${p;n;n;n;n;n;n;}' # other seds
###好像很容易理解了吧
# print section of file between two regular expressions (nclusive)
#打印文件中指定字符之間的部分(含字符在內(nèi))
sed -n '/Iowa/,/Montana/p' # case sensitive
###現(xiàn)在簡(jiǎn)單了吧.:)
SELECTIVE DELETION OF CERTAIN LINES:
# print all of file EXCEPT section between 2 regular expressions
#打印除指定字符之間部分之外的全文
sed '/Iowa/,/Montana/d'
###與上邊相似的簡(jiǎn)單
# delete duplicate, consecutive lines from a file (emulates "uniq")
# First line in a set of duplicate lines is kept, rest are deleted.
#刪除文件中重復(fù)的連續(xù)的行(似于"uniq"命令)
#重復(fù)行中第一行保留,其他刪除
sed '$!N; /^\(.*\)
\1$/!P; D'
###如果不是最后一行,就把下一行附加在模式空間,然后進(jìn)行查找%作
###"^"和"$"中間的內(nèi)容如果有重復(fù)就匹配成功.如果匹配不成功就用P打印
###第一行. 然后刪除第一行.
# delete duplicate, nonconsecutive lines from a file. Beware not to
# overflow the buffer size of the hold space, or else use GNU sed.
#刪除文件中重復(fù)的,但不連續(xù)的行。注意不要溢出保留空間的緩沖器的大小,
#否則使用GNU sed.
sed -n 'G; s/
/&&/; /^\([ -~]*
\).*
\1/d; s/
//; h; P'
###在我的linux環(huán)境執(zhí)行不了,出錯(cuò)是sed: -e expression #1, char 34:
###Invalid range end.是不是所謂的溢出保留空間的大小了呢?我也不得而知.
###大家補(bǔ)充吧.!!?????????????????
# delete the first 10 lines of a file
#刪除一個(gè)文件中前10行
sed '1,10d'
# delete the last line of a file
#刪除一個(gè)文件中最后1行
sed '$d'
###與上邊一個(gè)都是查找刪除
# delete the last 2 lines of a file
#刪除一個(gè)文件中最后2行
sed 'N;$!P;$!D;$d'
###如果理解了sed '$!N;$!D'是如何工作的,這句話也不在話下吧!
# delete the last 10 lines of a file
#刪除一個(gè)文件中后10行
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2
###和打印后10行相似.什么?打印后10那個(gè)沒看懂? /shakehand :)
###?????????????????
# delete every 8th line
# 每8行刪除1行
gsed '0~8d' # GNU sed only
sed 'n;n;n;n;n;n;n;d;' # other seds
###沒說的!
# delete ALL blank lines from a file (ame as "grep '.' ")
#刪除文件所有空白行(似于"grep '.' ")
sed '/^$/d' # method 1
sed '/./!d' # method 2
###這兩句就是告訴我們1.無內(nèi)容的刪除,2.有內(nèi)容的保留 : )
# delete all CONSECUTIVE blank lines from file except the first; also
# deletes all blank lines from top and end of file (emulates "cat -s")
#刪除文件中除一行空白行之外的所有連續(xù)空白行,也同時(shí)刪除所有從頭到尾的所
#有空白行(似于"cat -s")
sed '/./,/^$/!d' # method 1, allows 0 blanks at top, 1 at EOF
#方法1不允許文件頂部有空行,文件尾部可以
sed '/^$/N;/
$/D' # method 2, allows 1 blank at top, 0 at EOF
#方法2不允許文件尾部有空行,文件頂部可以
###兩個(gè)先選擇,后刪除命令.不多說了.
# delete all CONSECUTIVE blank lines from file except the first 2:
#刪除文件中連續(xù)空行中除前兩行空白行之外的所有空白行
sed '/^$/N;/
$/N;//D'
###跟上邊的命令相似,多了一步而已.
# delete all leading blank lines at top of file
#刪除文件開頭部分中的所有空白行
sed '/./,$!d'
###從有字符開始的行直到最后一行保留,其他刪除.
# delete all trailing blank lines at end of file
#刪除文件結(jié)尾部分中的所有空白行
sed -e :a -e '/^
*$/{$d;N;ba' -e '}' # works on all seds
sed -e :a -e '/^
*$/N;/
$/ba' # ditto, except for gsed 3.02*
###不行了要死了,還是高手說吧,我再看下去會(huì)瘋的!
###?????????????????????????????
# delete the last line of each paragraph
#刪除每個(gè)段落中最后1行
sed -n '/^$/{p;h;};/./{x;/./p;}'
###應(yīng)該是假設(shè)段落間用空行分隔
###命令執(zhí)行時(shí),如果不是空行那么交換模式空間和保留空間,如果交換后
###模式空間不為空,則打印模式空間中內(nèi)容;如果是空行,那么打印模式空間
###間中的內(nèi)容,也就是打印空行...以此類推,出現(xiàn)結(jié)果.
###終于完了,下邊的特殊應(yīng)用沒有加注,隨便翻譯了一下,可能不夠準(zhǔn)確,大家參考一下吧.
SPECIAL APPLICATIONS:
# remove nroff overstrikes (char, backspace)from man pages. The 'echo'
# command may need an -e switch if you use Unix System V or bash shell.
# 從man page頁里刪除所有overstrikes(字符,backspace).如果使用unix系統(tǒng)v
#或者bash shell,echo命令可能需要-e參數(shù).
sed "s/.`echo \\\b`//g" # double quotes required for Unix environment
#unix環(huán)境下需要雙引號(hào)
sed 's/.^H//g' # in bash/tcsh, press Ctrl-V and then Ctrl-H
#在bash/tcsh中,按Ctrl-V然后按Ctrl-H
sed 's/.\x08//g' # hex expression for sed v1.5
#sed v1.5中的hex表達(dá)式
# get Usenet/e-mail message header
# 獲得新聞組/e-mail信息的標(biāo)題部分
sed '/^$/q' # deletes everything after first blank line
# get Usenet/e-mail message body
#獲得新聞組/e-mail信息的主體部分
sed '1,/^$/d' # deletes everything up to first blank line
# get Subject header, but remove initial "Subject: " portion
#獲得題目的標(biāo)題,但是刪去開始的"Subject: "部分
sed '/^Subject: */!d; s///;q'
# get return address header
#獲得返回的地址標(biāo)題()
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'
# parse out the address proper. Pulls out the e-mail address by itself
# from the 1-line return address header (ee preceding script)
#正確解析地址。把email地址從一行中單獨(dú)提出來并返回地址頭()
sed 's/ *(*)/; s/>.*//; s/.*[: /'
# delete leading angle bracket & space from each line (nquote a message)
#刪除每行的尖括號(hào)和空格()信息不被引用)
sed 's/^> //'
# remove most HTML tags (ccommodates multiple-line tags)
#刪去大部分HTML標(biāo)簽(供多行標(biāo)簽))
sed -e :a -e 's/]*>//g;/zipup.bat
dir /b *.txt | sed "s/^\(*\).TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat
本文來自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u1/44068/showart_391470.html