给SHELL编程初学者 6

AWolfBoy 2004-10-23 03:38:00
接<给Shell 编程初学者 5>

# join pairs of lines side-by-side (like "paste")
#把两行合为一行(类似于"paste")
sed '$!N;s/\n/ /'
###这个命令改成 sed 'N;s/\n/ /'一样可以达到目的,不知前面
###的$!有什么用处...

# if a line ends with a backslash, append the next line to it
#如果一行以"\"结束,把下一行加在此行上
sed -e :a -e '/\\$/N; s/\\\n//; ta'
###循环操作,两次替换。

# if a line begins with an equal sign, append it to the previous line
# and replace the "=" with a single space
#如果一等号开始某一行,把这一行加到前一行后边,并且用一个空格替换等号
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
###和上边差不多,要注意两个新的命令:
### P命令--Print up to the first embedded newline of the current
###pattern space.打印当前模式空间中第一行。
###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.
###删除当前模式空间中第一行。开始新的循环,但是如果在模式空间中仍然
###有数据,那么跳过读取输入。

# add commas to numeric strings, changing "1234567" to "1,234,567"
#给数字串加逗号,把"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' # other seds
###(.*[0-9])表示零个或者多个字符(可能包含数字)+一个数字,而
###([0-9]{3})表示三个数字,然后不停的替换,直到条件不成立,也就是没有
###四个以上连续的数字出现就停止了.

# add commas to numbers with decimal points and minus signs (NU sed)
#给带有小数点和负号的数字的数字加上逗号
gsed ':a;s/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g;ta'
###没有gsed,不解释了

# 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")
#打印一个文件的前10行(模仿动作"head")
sed 10q

# print first line of file (emulates "head -1")
#打印一个文件的第一行(仿"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.
### 所以上边两个命令都清楚了,执行到第10行退出就打印前10行,执行第一行
###就退出就打印第一行

# print the last 10 lines of a file (emulates "tail")
#打印一个文件的后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 删除模式空间内第一个 newline 字母 \n 前的资料。
###命令N 把输入的下一行添加到模式空间中。
### b label:分支到脚本中带有标号的地方,如果标号不存就分支到脚本的末尾
###
waker
试着注一下,不知道对不对

如果我们只看sed -e :a -e '$q;N;ba'
这个循环不停的读入下 一行直到结尾,这样整个文本就形成一个由\n分割的链

现在加上11,$D
sed -e :a -e '$q;N;11,$D;ba'
如果文本不超过10行
模式空间将保留整个文本打印出来
如果文本大于10行
从第11行开始,在下一行加入到链中后,模式空间第一个由\n分割的记录将被删除,这样看起来就是链头被链尾挤出整个链,总是保持10个链环,循环结束后,链中保存的就是文件的后10行,最后印出结果

:em16:

# print the last 2 lines of a file (emulates "tail -2")
#打印一个文件的最后两行(仿"tail -2")
sed '$!N;$!D'
### 开始看不太懂,抄了CU精华一段
###sed '$!N;$!D' : 对文件倒数第二行以前的行来说,N 将当前行的下一行放到模
###式空间中以后,D 就将模式空间的内容删除了;到倒数第二行的时候,将最后一行
###附加到倒数第二行下面,然后最后一行不执行 D ,所以文件的最后两行都保存下来了。
###不知道是这段话说得有些含糊,还是我理解得有偏差,总觉得D命令解释成
###"将模式空间的内容删除了"有些让人糊涂.
###而我是这样理解的,不知道对不对.首先说D命令是 Delete up to the first
###embedded newline in the pattern space.也就是说D命令是删除模式空间中
###第一个换行符之前的内容,也就是删除第一行.然后D命令的解释还有一句,我认为
###这句很重要: Start next cycle, but skip reading from the input if there
### is still data in the pattern space.开始下一个循环,但是如果模式空间中有
###数据,则跳过从输入中读取数据.
###具体怎么工作呢? 假设文件为
### $ cat test.txt
### 1
### 2
### 3
### 4
### 5
### 那么当执行第一行时,$!N把第二行加入到模式空间中第一行后边,然后$!D把第一行
###内容删除,模式空间中只剩下第二行的内容.注意,此时由于D命令开始下一个循环,
###所以不打印模式空间中的内容! (这个地方也是我想了半天才这么解释的,我也知道
###很可能不对,欢迎拍砖,呵呵)由于D命令要求模式空间中有数据的话就跳过读取下一行,
###所以继续下一个循环又到了$!N,此时读入第三行加到第二行后边,....以此类推。
###执行到读入第5行附加在第四行后边,然后由于$!D得不到执行,所以第4行和第5行
###都被保留,命令结束,打印模式空间...

# print the last line of a file (emulates "tail -1")
#打印一个文件的最后一行(仿"tail -1")
sed '$!d' # method 1
sed -n '$p' # method 2
###哈哈,终于看懂了一个,你也看懂了吧 :)


# print only lines which match regular expression (emulates "grep")
#只打印匹配的一定字符的行(仿"grep")
sed -n '/regexp/p' # method 1
sed '/regexp/!d' # method 2
###明白参数-n和命令p和d就明白这两个命令.

(待续)
...全文
82 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧