﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Prayer-随笔分类-Shell</title><link>http://www.cppblog.com/prayer/category/7884.html</link><description>在一般中寻求卓越</description><language>zh-cn</language><lastBuildDate>Thu, 04 Apr 2019 13:20:02 GMT</lastBuildDate><pubDate>Thu, 04 Apr 2019 13:20:02 GMT</pubDate><ttl>60</ttl><item><title>sed -i命令详解</title><link>http://www.cppblog.com/prayer/archive/2019/04/04/216337.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 04 Apr 2019 09:49:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/04/04/216337.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216337.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/04/04/216337.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216337.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216337.html</trackback:ping><description><![CDATA[<div>https://www.cnblogs.com/ev-zhk/p/4277023.html<br /><div data-find="_2" style="margin: 5px 0px; font-size: 12px; line-height: 18px;"><pre data-find="_1" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;">[root@www ~]# <span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> [-<span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">nefr] [动作] 选项与参数： </span>-n ：使用安静(silent)模式。在一般 <span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> 的用法中，所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -<span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">n 参数后，则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。 </span>-e ：直接在命令列模式上进行 <span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;"> 的动作编辑； </span>-f ：直接将 <span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> 的动作写在一个文件内， -f filename 则可以运行 filename 内的 <span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;"> 动作； </span>-r ：<span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;"> 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法) </span>-<span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">i ：直接修改读取的文件内容，而不是输出到终端。  动作说明： [n1[,n2]]</span><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">function</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;"> n1, n2 ：不见得会存在，一般代表『选择进行动作的行数』，举例来说，如果我的动作是需要在 </span><span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">10</span> 到 <span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">20</span> 行之间进行的，则『 <span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">10</span>,<span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">20</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">[动作行为] 』  </span><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">function</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">： a ：新增， a 的后面可以接字串，而这些字串会在新的一行出现(目前的下一行)～ c ：取代， c 的后面可以接字串，这些字串可以取代 n1,n2 之间的行！ d ：删除，因为是删除啊，所以 d 后面通常不接任何咚咚； i ：插入， i 的后面可以接字串，而这些字串会在新的一行出现(目前的上一行)； p ：列印，亦即将某个选择的数据印出。通常 p 会与参数 </span><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -<span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">n 一起运行～ s ：取代，可以直接进行取代的工作哩！通常这个 s 的动作可以搭配正规表示法！例如 </span><span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">1</span>,20s/old/new/g 就是啦！</pre><div style="margin: 5px 0px 0px; line-height: 1.5 !important;"><span style="margin: 0px; padding: 0px 5px 0px 0px; line-height: 1.5 !important;"><a title="复制代码" style="margin: 0px; padding: 0px; color: #444444; text-decoration: underline; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="margin: 0px; padding: 0px; max-width: 660px; height: auto; border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;"><br style="margin: 0px; padding: 0px;" /><strong style="margin: 0px; padding: 0px;">sed -i</strong>&nbsp;就是直接对文本文件进行操作的</p><div style="margin: 5px 0px; font-size: 12px; line-height: 18px;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -i <span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">s/原字符串/新字符串/</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span> /home/<span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">1</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">.txt </span><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -i <span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">s/原字符串/新字符串/g</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span> /home/<span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">1</span>.txt</pre></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;"><br style="margin: 0px; padding: 0px;" />这两条命令的区别就是，看示例吧</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;">这是1.txt的内容</p><div style="margin: 5px 0px; font-size: 12px; line-height: 18px;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">#<span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">cat</span> 1</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">.txt d ddd #ff</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;">再看执行这两条命令的区别吧</p><div style="margin: 5px 0px; font-size: 12px; line-height: 18px;"><div style="margin: 5px 0px 0px; line-height: 1.5 !important;"><span style="margin: 0px; padding: 0px 5px 0px 0px; line-height: 1.5 !important;"><a title="复制代码" style="margin: 0px; padding: 0px; color: #444444; text-decoration: underline; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="margin: 0px; padding: 0px; max-width: 660px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -i <span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">s/d/7523/</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span> /home/<span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">1</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">.txt 执行结果 </span><span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">7523</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;"> 7523</span><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">dd</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;"> #ff  </span><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -i <span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">s/d/7523/g</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span> /home/<span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">1</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;">.txt 执行结果 </span><span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">7523</span> <span style="margin: 0px; padding: 0px; color: #800080; line-height: 1.5 !important;">752375237523</span><span style="margin: 0px; padding: 0px; line-height: 1.5 !important;"> #ff</span></pre><div style="margin: 5px 0px 0px; line-height: 1.5 !important;"><span style="margin: 0px; padding: 0px 5px 0px 0px; line-height: 1.5 !important;"><a title="复制代码" style="margin: 0px; padding: 0px; color: #444444; text-decoration: underline; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="margin: 0px; padding: 0px; max-width: 660px; height: auto; border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">去掉&nbsp;&#8220;行首&#8221;&nbsp;带&#8220;@&#8221;的首字母@</strong></p><div style="margin: 5px 0px; font-size: 12px; line-height: 18px;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -i <span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">s/^@//</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span> <span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">file</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">特定字符串的行前插入新行</strong></p><div style="margin: 5px 0px; font-size: 12px; line-height: 18px;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -i <span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">/特定字符串/i 新行字符串</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">' <span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">file</span></span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">特定字符串的行后插入新行</strong></p><div style="margin: 5px 0px; font-size: 12px; line-height: 18px;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -i <span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">/特定字符串/a 新行字符串</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span> <span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">file</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">特定字符串的删除</strong></p><div style="margin: 5px 0px; font-size: 12px; line-height: 18px;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed</span> -i <span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">'</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">/字符串/d</span><span style="margin: 0px; padding: 0px; color: #800000; line-height: 1.5 !important;">' </span><span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">file</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 18px; color: #444444; font-family: tahoma, arial, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p></div><img src ="http://www.cppblog.com/prayer/aggbug/216337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-04-04 17:49 <a href="http://www.cppblog.com/prayer/archive/2019/04/04/216337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sed中使用变量替换以及执行外部命令</title><link>http://www.cppblog.com/prayer/archive/2019/04/04/216336.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 04 Apr 2019 09:46:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/04/04/216336.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216336.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/04/04/216336.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216336.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216336.html</trackback:ping><description><![CDATA[<div>https://blog.csdn.net/halazi100/article/details/41722021<br /><br /><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">在使用sed对日志或者其它文本进行parse的过程当中，有时候我们需要引用外部变量的值，<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />或者获取一个shell命令执行的结果，以便达到更加可观的输出结果。这里介绍如何做到。<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />sed中使用变量替换<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />1.sed命令使用双引号的情况下，使用$var直接引用<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />$ echo|sed "s/^/$RANDOM.rmvb_/g"<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;29328.rmvb_</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">如果替换的变量内容中含有/符号则会提示如下错误，如<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />查找当前目录下的目录文件并将相对路径替换为绝对路径<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />find . -type f | sed -n "s/\./$PWD/p"<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />sed: -e expression #1, char 19: unknown option to `s'<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />从语法上看，没有任何问题；但由于变量中包含有&#8220;/&#8221;作为分隔符，这会和sed的替换操作的分隔符&#8220;/&#8221;引起混淆；所以，只要不使用&#8220;/&#8221;做分隔符就可以解决这个问题，如果使用&#8220;%&#8221;而不是&#8220;/&#8221;来作为sed的替换操作的分隔符，就不会出错。其实使用#或%或;作为分隔符也是可以的，只要不会与替换中有相同的而且不是元字符的特殊符号都是可以的；使用时可以根据情况灵活选择。<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />find . -type f | sed -n "s%\.%$PWD%p"<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />find . -type f | sed -n "s#\.#$PWD#p"</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"># 上面例子引用了一个环境变量$RANDOM的值<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />2.sed命令使用单引号的情况下，使用'"$var"'引用<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />类似，我们可以看到<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />$ echo|sed 's/^/'"$RANDOM"'.rmvb_/g'<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;31338.rmvb_<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />sed中执行外部命令<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />1.sed命令使用单引号的情况下使用'`shell command`'或者'$(shell command)'引用命令执行的结果<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />还是以上面案例分析，例子如下<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />$ echo|sed 's/^/'`echo $RANDOM`'.rmvb_/g'<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;8063.rmvb_<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"># 上面的例子使用了旧式的命令替换，也可以采用新式的命令替换方法，如下<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />$ echo|sed 's/^/'$(echo $RANDOM)'.rmvb_/g'<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;18554.rmvb_<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"># 下面例子取用当前日期作为结果的一部分，如下<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />$ echo|sed 's/^/'$(date +"%Y%m%d")'.rmvb_/g'<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;20120108.rmvb_<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">2.sed命令使用双引号的情况下直接`shell command`或者$(shell command)引用命令执行的结果<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">类似的，双引号的情况，如下<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />$ echo|sed "s/^/$(date +"%Y%m%d").rmvb_/g"<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;20120108.rmvb_<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"># 使用环境变量$RANDOM以及旧式命令替换的例子<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />$ echo|sed "s/^/`echo $RANDOM`.rmvb_/g"<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;4988.rmvb_<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />总结<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />在sed语句里面，变量替换或者执行shell命令，双引号比单引号少绕一些弯子</p></div><img src ="http://www.cppblog.com/prayer/aggbug/216336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-04-04 17:46 <a href="http://www.cppblog.com/prayer/archive/2019/04/04/216336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 比较两个文件夹不同 (diff命令, md5列表)</title><link>http://www.cppblog.com/prayer/archive/2019/04/04/216335.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 04 Apr 2019 09:46:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/04/04/216335.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216335.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/04/04/216335.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216335.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216335.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong><span style="color: #ff0000;">比较文件夹diff，可以直接使用diff命令</span></strong></p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">[root@~]# diff -urNa dir1 dir2<br />　　-a Treat all files as text and compare them line-by-line, even if they do not seem to be text.<br />　　-N, --new-file<br />　　　　In directory comparison, if a file is found in only one directory, treat it as present but empty in the other directory.<br />　　-r When comparing directories, recursively compare any subdirectories found.</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">　　-u Use the unified output format.</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><span style="color: #ff0000;"><strong>比较文件夹diff，也可以比较文件MD5列表。下面命令可以获取文件夹中文件md5列表</strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">find /home/ -type f -not \( -name '.*' \) -exec md5sum {} \;</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">说明：(1)&nbsp;/home/文件目录</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">　　 &nbsp; (2)&nbsp;-type f 文件类型为普通文件</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">　　 &nbsp; (3)&nbsp;-not \( -name '.*' \) &nbsp;过滤掉隐藏文件。可以过滤掉不需要考虑的文件</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(4)&nbsp;-exec md5sum {} \; &nbsp;对每个文件执行md5sum命令&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><span style="color: #ff0000;"><strong>&nbsp;用tar命令压缩后，比较文件的MD5是不行的。tar压缩会带上文件的时间</strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><img src="https://images2015.cnblogs.com/blog/466768/201703/466768-20170303081158188-1578572513.png" alt="" style="border: 0px; max-width: 900px; height: auto;" /></p><img src ="http://www.cppblog.com/prayer/aggbug/216335.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-04-04 17:46 <a href="http://www.cppblog.com/prayer/archive/2019/04/04/216335.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SHELL 在指定行的前/后插入指定内容</title><link>http://www.cppblog.com/prayer/archive/2019/04/04/216334.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 04 Apr 2019 09:13:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/04/04/216334.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216334.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/04/04/216334.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216334.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216334.html</trackback:ping><description><![CDATA[<div>https://www.jianshu.com/p/66f79ad53406<br /><br /><h3>如果知道行号可以用下面的方法</h3><pre bash"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">sed -i <span style="box-sizing: border-box; color: #98c379;">'88 r b.file'</span> a.file    <span style="box-sizing: border-box; color: #929292;">#在a.txt的第88行插入文件b.txt</span> awk <span style="box-sizing: border-box; color: #98c379;">'1;NR==88{system("cat b.file")}'</span> a.file &gt; a.file </code></pre><h3>如果不知道行号，可以用正則匹配</h3><pre bash"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">sed -i <span style="box-sizing: border-box; color: #98c379;">'/regex/ r b.txt'</span> a.txt <span style="box-sizing: border-box; color: #929292;"># regex是正则表达式</span> awk <span style="box-sizing: border-box; color: #98c379;">'/target/{system("cat b.file")}'</span> a.file &gt; c.file </code></pre><h3>sed的話如果不改变源文件，可以去掉-i开关，修改会输出到STDOUT</h3><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">原文件：</p><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># cat -n file </span>      <span style="box-sizing: border-box; color: #d19a66;">1</span>  aaaa      <span style="box-sizing: border-box; color: #d19a66;">2</span>  bbbb      <span style="box-sizing: border-box; color: #d19a66;">3</span>  cccc      <span style="box-sizing: border-box; color: #d19a66;">4</span>  dddd </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">现在要在第二行即&#8220;bbbb&#8221;行的下面添加一行，内容为&#8220;xiaowu&#8221;</p><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># sed '/bbbb/a\xiaowu' file </span> aaaa bbbb xiaowu cccc dddd </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">如果要加两行&#8220;xiaowu&#8221;可以用一下语句，注意用&#8220;\n&#8221;换行</p><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># sed '/bbbb/a\xiaowu\nxiaowu' file </span> aaaa bbbb xiaowu xiaowu cccc dddd </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">如果要在第二行即&#8220;bbbb&#8221;行的上添加一行，内容为&#8220;xiaowu&#8221;，可以把参数&#8220;a&#8221;换成&#8220;i&#8221;</p><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># sed '/b/i\xiaowu' file </span> aaaa xiaowu bbbb cccc dddd </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">以上文件中只有一行匹配，如果文件中有两行或者多行匹配，结果有是如何呢？</p><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># cat -n file </span>      <span style="box-sizing: border-box; color: #d19a66;">1</span>  aaaa      <span style="box-sizing: border-box; color: #d19a66;">2</span>  bbbb      <span style="box-sizing: border-box; color: #d19a66;">3</span>  cccc      <span style="box-sizing: border-box; color: #d19a66;">4</span>  bbbb      <span style="box-sizing: border-box; color: #d19a66;">5</span>  dddd </code></pre><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># sed '/bbbb/a\xiaowu' file </span> aaaa bbbb xiaowu cccc bbbb xiaowu dddd </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">由结果可知，每个匹配行的下一行都会被添加&#8220;xiaowu&#8221;</p><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">那么如果指向在第二个&#8220;bbbb&#8221;的下一行添加内容&#8220;xiaowu&#8221;，该如何操作呢？<br style="box-sizing: border-box;" />可以考虑先获取第二个&#8220;bbbb&#8221;行的行号，然后根据行号在此行的下一行添加&#8220;xiaowu&#8221;</p><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">获取第二个&#8220;bbbb&#8221;行的行号的方法：<br style="box-sizing: border-box;" />方法一：</p><pre objectivec"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #61aeee;"># cat -n file |grep b |awk '{print $1}'|sed -n <span style="box-sizing: border-box; color: #98c379;">"2"</span>p</span> <span style="box-sizing: border-box; color: #d19a66;">4</span> </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">方法二：</p><pre objectivec"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #61aeee;"># sed -n '/bbbb/=' file |sed -n <span style="box-sizing: border-box; color: #98c379;">"2"</span>p</span> <span style="box-sizing: border-box; color: #d19a66;">4</span> </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">由结果可知第二个&#8220;bbbb&#8221;行的行号为4，然后再在第四行的前或后添加相应的内容:</p><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># sed -e '4a\xiaowu' file </span> aaaa bbbb cccc bbbb xiaowu dddd </code></pre><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># sed -e '4a\xiaowu\nxiaowu' file </span> aaaa bbbb cccc bbbb xiaowu xiaowu dddd </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;">向指定行的末尾添加指定内容，比如在&#8220;ccccc&#8221;行的行尾介绍&#8220; eeeee&#8221;</p><pre ruby"="" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 15px; margin-top: 0px; margin-bottom: 20px; line-height: 1.42857; word-wrap: normal; color: #abb2bf; background-color: #282c34; border: 1px solid #cccccc; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-break: break-word !important;"><code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; color: inherit; background-color: transparent; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; padding: 0px; border: none; vertical-align: middle;">[root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># cat file</span> aaaaa bbbbb ccccc ddddd [root@xiaowu shell]<span style="box-sizing: border-box; color: #929292;"># sed 's/cc.*/&amp; eeeee/g' file</span> aaaaa bbbbb ccccc eeeee ddddd </code></pre><p style="box-sizing: border-box; margin: 0px 0px 25px; color: #2f2f2f; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; font-size: 16px; line-height: 27px; background-color: #ffffff; word-break: break-word !important;"><a href="http://www.360doc.com/content/14/1125/19/7044580_428024359.shtml" target="_blank" rel="nofollow" style="box-sizing: border-box; background-color: transparent; color: #3194d0; text-decoration: none; cursor: pointer;">原文链接</a></p></div><img src ="http://www.cppblog.com/prayer/aggbug/216334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-04-04 17:13 <a href="http://www.cppblog.com/prayer/archive/2019/04/04/216334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux Sftp 下载整个文件目录</title><link>http://www.cppblog.com/prayer/archive/2019/03/18/216302.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 18 Mar 2019 06:42:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/03/18/216302.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216302.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/03/18/216302.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216302.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216302.html</trackback:ping><description><![CDATA[<p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei'; word-wrap: break-word;">直接看图：</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><img src="https://img-blog.csdn.net/20180503111757090" alt="" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; max-width: 100%; word-wrap: break-word; cursor: -webkit-zoom-in;" /></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp; &nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei'; word-wrap: break-word;">有两个特点：</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px 27pt; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei'; word-wrap: break-word;">1：使用-r参数</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px 27pt; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei'; word-wrap: break-word;">2：在目录后面使用"."号<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei'; word-wrap: break-word;">这样的话就可以把</span>/opt/merkle&nbsp;<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei'; word-wrap: break-word;">目录和子目录里面的文件全部下载到本地了。</span></p><img src ="http://www.cppblog.com/prayer/aggbug/216302.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-03-18 14:42 <a href="http://www.cppblog.com/prayer/archive/2019/03/18/216302.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell脚本报错"[: =: unary operator expected"的解决方案</title><link>http://www.cppblog.com/prayer/archive/2019/03/01/216275.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Fri, 01 Mar 2019 07:20:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/03/01/216275.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216275.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/03/01/216275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216275.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216275.html</trackback:ping><description><![CDATA[<p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">&nbsp; 在匹配字符串相等时，我用了类似这样的语句：</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">if [ $STATUS == "OK" ]; then&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">echo "OK"</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">fi</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">&nbsp;&nbsp;&nbsp; 在运行时出现了&#8220; [: =: unary operator expected&#8221; 的错误，就一直找不到原因，尝试了删除等号两侧的空格和括号里的空格都不管用。最后<a href="https://www.baidu.com/s?wd=baidu&amp;tn=24004469_oem_dg&amp;rsv_dl=gh_pl_sl_csd" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">baidu</a>了一下，才找到原因，在条件表达式外再添加一层&#8220;[]&#8221;，就不会出错了，如下：</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">if [[ $STATUS = "OK" ]];&nbsp;</span><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">then &nbsp;</span>&nbsp;&nbsp;</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">echo "OK"</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">fi&nbsp;</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">&nbsp;&nbsp;&nbsp; 究其原因，是因为如果变量STATUS值为空，那么<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: Arial; word-wrap: break-word;">条件表达式</span>就成了 [ = "OK"] ，显然 [ 和 "OK" 不相等并且缺少了&nbsp;</span><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">[ 符号，所以报了这样的错误。当然不总是出错，如果变量STATUS值不为空，程序就正常了，所以这样的错误还是很隐蔽的。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">&nbsp;&nbsp;&nbsp; 或者，用下面的方法也能避免这种错误：</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">if [ "$STATUS"x == "OK"x ]; then&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">echo</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">"OK"</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">fi。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">当然，x也可以是其他字符。顺便提一点，shell中有没有双引号在很多情况下是一致的。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #333333; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">转自：<a href="http://hi.baidu.com/vishare/blog/item/bd8ab9ee289753252cf53417.html" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #336699; text-decoration: none; cursor: pointer; word-wrap: break-word;">http://hi.baidu.com/vishare/blog/item/bd8ab9ee289753252cf53417.html</a></span></p><img src ="http://www.cppblog.com/prayer/aggbug/216275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-03-01 15:20 <a href="http://www.cppblog.com/prayer/archive/2019/03/01/216275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell脚本字符串截取的8种方法</title><link>http://www.cppblog.com/prayer/archive/2019/01/24/216219.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 24 Jan 2019 06:18:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/01/24/216219.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216219.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/01/24/216219.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216219.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216219.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: https://www.cnblogs.com/zwgblog/p/6031256.html假设有变量 var=http://www.aaa.com/123.htm.1. # 号截取，删除左边字符，保留右边字符。1echo ${var#*//}&nbsp;其中 var 是变量名，# 号是运算符，*// 表示从左边开始删除第一个 // 号及左边的所有字符即删除 http://结果是 ：www.aaa...&nbsp;&nbsp;<a href='http://www.cppblog.com/prayer/archive/2019/01/24/216219.html'>阅读全文</a><img src ="http://www.cppblog.com/prayer/aggbug/216219.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-01-24 14:18 <a href="http://www.cppblog.com/prayer/archive/2019/01/24/216219.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux fg bg ctrl + z jobs &amp; 等命令</title><link>http://www.cppblog.com/prayer/archive/2010/11/29/135006.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 29 Nov 2010 10:50:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/11/29/135006.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/135006.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/11/29/135006.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/135006.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/135006.html</trackback:ping><description><![CDATA[<p>fg、bg、jobs、&amp;、ctrl + z都是跟系统任务有关的，虽然现在基本上不怎么需要用到这些命令，但学会了也是很实用的<br>一。&amp; 最经常被用到<br>&nbsp; &nbsp;这个用在一个命令的最后，可以把这个命令放到后台执行<br>二。ctrl + z<br>&nbsp; &nbsp; &nbsp;可以将一个正在前台执行的命令放到后台，并且暂停<br>三。jobs<br>&nbsp; &nbsp; &nbsp;查看当前有多少在后台运行的命令<br>四。fg<br>&nbsp; &nbsp; &nbsp;将后台中的命令调至前台继续运行<br>&nbsp; &nbsp;如果后台中有多个命令，可以用 fg %jobnumber将选中的命令调出，%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)<br>五。bg<br>&nbsp; &nbsp; &nbsp;将一个在后台暂停的命令，变成继续执行<br>&nbsp; &nbsp;如果后台中有多个命令，可以用bg %jobnumber将选中的命令调出，%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)</p>
<img src ="http://www.cppblog.com/prayer/aggbug/135006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-11-29 18:50 <a href="http://www.cppblog.com/prayer/archive/2010/11/29/135006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell数组详解</title><link>http://www.cppblog.com/prayer/archive/2010/09/15/126653.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 15 Sep 2010 05:26:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/15/126653.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126653.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/15/126653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126653.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126653.html</trackback:ping><description><![CDATA[<div>
<p>Bash中还可以使用<span class=highlight><font color=#ff0000><strong>数组</strong></font></span>变量,其赋值有两种:<br><br>(1) name = (value1 ... valuen) 此时下标从0开始<br>(2) name[index] = value<br><br><span class=highlight><font color=#ff0000><strong>数组</strong></font></span>下标的范围没有任何限制,同时也不必使用连续的分量.</p>
<hr style="COLOR: rgb(102,102,102)" SIZE=1>
<!-- / icon and title --><!-- message -->
<div>$ A=(a b c def)<br><br>==================================================<br>$ echo ${A[@]}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //取全部元素<br>a b c def<br><br>=================================================<br><br>$ echo ${A[0]}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//取第一个元素<br>a<br><br>=================================================<br><br>//取得<span class=highlight><strong><font color=#ff0000>数组</font></strong></span>元素的个数<br>$&nbsp;echo ${#A[@]}<br>4<br>$&nbsp;echo ${#A[*]}<br>4<br>$ echo ${#A[3]}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//取得元素3的长度</div>
<div>$<br><br>==================================================<br><br>$&nbsp;A[3]=yaoshuyin&nbsp;&nbsp;&nbsp; //将第三个元素重新赋值<br>$&nbsp;echo ${A[@]}<br>a b c yaoshuyin<br><br>==================================================<br>//清除变量<br>$&nbsp;unset A<br>$&nbsp;echo ${A[@]}</div>
<div>$<br><br>==================================================<br><br>//清空变量,即将值变为空<br>$&nbsp;A=<br>$&nbsp;echo ${A[@]}</div>
<div>$</div>
<div>==================================================<br><br>A=B <br>B=C <br>unset $A 事实上所取消的变量是 B 而不是 A<br><br><br>=======================示例 while循环========================<br><br><span style="FONT-WEIGHT: bold">#建立数组</span><br><span style="FONT-WEIGHT: bold">arrSource</span>=(<span style="COLOR: rgb(153,1,2)">"arrJobs.php"</span>&nbsp; <span style="COLOR: rgb(204,51,51)">"arrSubHangye.php"</span> <span style="COLOR: rgb(204,51,51)">"arrFirst.php"</span> )<br><br><span style="FONT-WEIGHT: bold">arrDest</span>=(<span style="COLOR: rgb(204,51,51)">"buildhr"&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(255,1,2)">\</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(204,51,51)">"buildtrain/htdocs"&nbsp;</span> <span style="COLOR: rgb(255,1,2)">\</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(204,51,51)">"bankhr"&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(255,1,2)">\</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(204,51,51)">"healthr"</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(255,1,2)"> \</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(204,51,51)">"elehr"&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(204,51,51)">\</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br><br><span style="FONT-WEIGHT: bold">#取数组无元素个数</span><br>lenArrSource=${#arrSource[*]}<br>lenArrDest=${#arrDest[*]}<br><br><br><span style="FONT-WEIGHT: bold">#循环列出数组元素</span><br>i=0<br>while&nbsp; [ $i -lt $lenArrSource ]<br>do<br>&nbsp;&nbsp; echo ${arrSource[$i]}<br>&nbsp;&nbsp; let i++<br>done<br><br><br>i=0<br>while&nbsp; [ $i -lt $lenArrDest ]<br>do</div>
<!-- / message -->
<p>&nbsp;&nbsp; echo ${arrDest[$i]}</p>
<br>
<p>&nbsp;&nbsp; let i++</p>
<br>
<p>done</p>
<br><br><br>
<p>=======================示例： for循环===============================</p>
<br><br><span style="FONT-WEIGHT: bold">#源文件</span><br>
<p>arrSource=("/home/800hr/htdocs/login_jump.php")</p>
<br><br><span style="FONT-WEIGHT: bold">#目标网站</span><br>
<p>arrDest=(ithr elehr buildhr bankhr healthr&nbsp; ctvhr chenhr mechr clothr cneduhr 56hr tourhr foodhr greenhr cnlawhr waimaohr)</p>
<br><br>
<p>for outer in ${arrSource[*]}&nbsp;&nbsp;&nbsp;</p>
<span style="FONT-WEIGHT: bold">#${arrSource[*]} 是数组中的所有元素</span><br>
<p>do</p>
<br>
<p>&nbsp;&nbsp; for inner in ${arrDest[*]}</p>
<br>
<p>&nbsp;&nbsp; do</p>
<br>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo&nbsp; "ln -s $outer /home/${inner}/campus/"</p>
<br>
<p>&nbsp;&nbsp; done</p>
<br>
<p>done</p>
</div>
<img src ="http://www.cppblog.com/prayer/aggbug/126653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-15 13:26 <a href="http://www.cppblog.com/prayer/archive/2010/09/15/126653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sed的一篇强例子集锦的翻译(转)</title><link>http://www.cppblog.com/prayer/archive/2010/09/15/126638.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 15 Sep 2010 03:13:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/15/126638.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126638.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/15/126638.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126638.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126638.html</trackback:ping><description><![CDATA[sed的一篇强例子集锦的翻译 <br>翻译了一下 <br><a href="http://bbs.chinaunix.net/forum/24/20040514/325187.html" target=_blank><font color=#0000ff><u>http://bbs.chinaunix.net/forum/24/20040514/325187.html</u></font></a><br><br>我是新手，翻译得不好，加注得马马虎虎，很多地方都是凭自己的理解写的。由于刚开始学sed，所以很多地方写得很初级，呵呵，难免有些罗嗦。写到最后又有些头晕，还请大虾们多多指点，里头好几个命令我解释不清楚，如不吝赐教，感激不尽！&nbsp;&nbsp;<br><br>FILE SPACING: <br># double space a file <br>#使一个文件中每一行都占用两行空间(就是在每一行后边插一行空行) <br>sed G <br>###sed 中G命令的解释为append hold space to pattern space. <br>###就是在当前位置后加一行保留空间中的内容，无任何动作时，保留空间为空行 <br>###所以就double space a file 了，呵呵． <br># double space a file which already has blank lines in it. Output file <br># should contain no more than one blank line between lines of text. <br>#假若文件已经含有空白行在其中，使一个文件中每一行占用两行 <br>#空间。输出文件中文本行之间不含有超过一行的空行 <br>sed '/^$/d;G' <br>###先用sed '/^$/d' 查找并删除空行；然后用 sed G插入空行 <br># triple space a file <br>#使一个文件中每一行都占用三行空间(就是在每一行后边插两行空行) <br>sed 'G;G' <br>###不用说了吧，重复两次sed G. <br># undo double-spacing (assumes even-numbered lines are always blank) <br>#撤销占用两行空间的%作(假设偶数行都是空白行) <br>sed 'n;d' <br>###sed 中命令n的解释为Read　the next line of input into the pattern space． <br>###所以我理解为用sed n 读入下一行兵紧接着用sed d 删除，如果隔两行删除一行那么 <br>###用sed 'n,n,d',要是隔100行删除一行呢....什么???!!!你要写100个n???!!! <br># insert a blank line above every line which matches "regex" <br>#在每个含有字符串regex的行上插入一行空白行 <br>sed '/regex/{x;p;x;}' <br>###sed 中命令x解释为Exchange the contents of the hold and pattern spaces. <br>###我的理解也就是交换保留空间与模式空间的内容 <br>###sed 中命令p为Print the current pattern space．就是打印模式空间中的内容． <br>###所以理解为保留空间中开始为空行，模式空间中经过sed '/regex/'查询后为包含 <br>###regex内容的那一行，1)x;交换模式空间和保留空间的内容，此时模式空间中内容 <br>###为空行，保留空间中内容为含有regex内容的行， 2)p；命令打印模式空间内容( <br>###空行)，在原文中含有regex内容的那一行的位置出现两行空行，其中后一行为 <br>###模式空间中的内容，3)x;后交换模式空间和保留空间中的内容，．．．．结果就是在原 <br>###来出现regex的位置前一行加入了一行空行。 <br># insert a blank line below every line which matches "regex" <br># 在每个含有字符串regex的行下插入一行空白行 <br>sed '/regex/G' <br>###比较简单，查找后在后边加入一空行 <br># insert a blank line above and below every line which matches "regex" <br>#在每个含有字符串regex的行上，下各插入一行空白行 <br>sed '/regex/{x;p;x;G;}' <br>###兄弟两个sed '/regex/G'和sed '/regex/{x;p;x;}'合作的结果． <br>NUMBERING: <br># number each line of a file (simple left alignment) Using a tab (see <br># note on '\t' at end of file)instead of space will preserve margins. <br>#给文件每一行加上数字序号。用TAB制表符替换空间来保留空白(?) <br>#(在数字序号和文本中间加一TAB制表符) <br>sed = filename | sed 'N;s/<br>/\t/' <br>###sed = filename的功能是 Print the current line number. <br>###但是这个功能是在每一行前面另加一行，并且显示行号,而不是直接在行首加序号 <br>###sed中命令N的解释为Append the next line of input into the pattern space. <br>###也就是把当前行后一行的内容加在当前行后边． <br>###sed中命令s/regexp/replacement/解释为Attempt to match regexp against the <br>###pattern space. If successful, replace that portion matched with <br>### replacement.大概意思是在模式空间外匹配regexp，如果成功，使用匹配replace <br>###ment的内容替换regexp.说白了就是查找替换吧．<br>是换行符,\t是TAB制表符, <br>###所以整个命令的意思也就出来了． <br># number each line of a file (nnumber on left, right-aligned) <br>#给文件每一行加上数字序号(数字在左边，向右对齐？) <br>sed = filename | sed 'N; s/^/ /; s/ *\(.\{6,\}\)<br>/\1 /' <br>### 前面不用说了，但是后边...... <br>###s/ *\(.\{6,\}\)<br>/\1 /' 这个地方确实不是很明白!~~ <br># number each line of file, but only print numbers if line is not blank <br>#给文件每一行加上数字序号，但是仅当行非空时打印数字 <br>sed '/./=' filename | sed '/./N; s/<br>/ /' <br>###sed '/./=' filename的用处是查找除非空行赋予行号,sed '/./N; s/<br>/ /'查找非 <br>##空行并把后一行附加到当前行,然后用空格替换换行符<br><br># count lines (emulates "wc -l") <br>#统计行数(类似于 "wc -l") <br>sed -n '$=' <br>#sed中参数n的含义是suppress automatic printing of pattern space,也就是限制 <br>###自动打印模式空间中内容的功能， '$='中$的含义是Match the last line，=前边 <br>###已经说过了，就是打印行号，所以匹配最后一行而且只打印行号不打印内容，就是 <br>###"wc -l"了 <br>TEXT CONVERSION AND SUBSTITUTION: <br># IN UNIX ENVIRONMENT: convert DOS newlines (cR/LF)to Unix format <br>#在UNIX环境下：转换DOS换行符(?)(cR/LF)UNIX格式 <br>sed 's/.$//' # assumes that all lines end with CR/LF <br># 假设所有的行都以CR/LF结尾 <br>###可能在DOS中的ASCII码(包括CR/LF)到了UNIX中都成了单字符吧，又因为".$"代表 <br>###每行最后一个字符，所以把它们替换掉就OK了．CR/LF是啥？CR---ASCII Carriage <br>###Return(ASCII 回车) ,LF----ASCII Linefeed (ASCII换行) <br>sed 's/^M$//' # in bash/tcsh, press Ctrl-V then Ctrl-M <br>#在bash/tcsh中，按下Ctrl-V然后按 Ctrl-M <br>###没啥说的，就是查找替换，注意命令中"^M"在输入时一定是按下Ctrl-V然后按 Ctrl-M <br>###如果输入成ctrl+6键，然后输入一个大写M,什么替换也完成不了啦． <br>sed 's/\x0D$//' # gsed 3.02.80, but top script is easier <br># ??? <br>###不是很了解！高手说一下吧！ <br># IN UNIX ENVIRONMENT: convert Unix newlines (F)to DOS format <br>#在unix环境中：转换Unix换行符(F)DOS格式 <br>sed "s/$/`echo -e \\\r`/" # command line under ksh <br>　　　　　　　　　　　　　#在ksh下的命令行 <br>sed 's/$'"/`echo \\\r`/" # command line under bash <br>　　　　　　　　　　　　 #在bash下的命令行 <br>sed "s/$/`echo \\\r`/" # command line under zsh <br>#在zsh下的命令行 <br>sed 's/$/\r/' # gsed 3.02.80 <br>　　　　　　　# gsed3.02.80版本下的命令行 <br>###以上四个命令是在不同的shell版本下用\r(好象就是ASCII码下的CR)替换行尾 <br># IN DOS ENVIRONMENT: convert Unix newlines (F)to DOS format <br>#在DOS环境下转换Unix换行符到DOS格式 <br>sed "s/$//" # method 1 <br>sed -n p # method 2 <br>###这句又不是很了解，本来$就是行尾了，把行尾替换成空，那就变成了DOS格式了吗？ <br>###下边一句也很奇怪，参数-n是suppress automatic printing of pattern space，命 <br>###令p是Print the current pattern space，一正一反就换成DOS格式了？乖乖~~ <br># IN DOS ENVIRONMENT: convert DOS newlines (cR/LF)to Unix format <br>#在Dos环境下：转换DOS换行符为UNIX格式 <br># Cannot be done with DOS versions of sed. Use "tr" instead. <br>#用DOS版本的sed不能做到这点，用"tr"代替． <br>tr -d \r outfile # GNU tr version 1.22 or higher <br>　　　　　　　　　　　　　#GNU tr 1.22版本或者更高版本 <br># delete leading whitespace (spaces, tabs)from front of each line <br># aligns all text flush left <br>#删除每一行开头的空白(空格，TAB)左对齐排列全文． <br>sed 's/^[ \t]*//' # see note on '\t' at end of file <br>　　　　　　　　　# ??? <br>### 又是替换成空，^[ \t]* 的含义为以空格或者TAB键开始的(或者是他们的组合)行． <br># delete trailing whitespace (spaces, tabs)from end of each line <br>#从每一行结尾处删除最后的空格(空格,TAB) <br>sed 's/[ \t]*$//' # see note on '\t' at end of file <br>#?? <br>### 跟上边的命令"前呼后拥"呀． <br># delete BOTH leading and trailing whitespace from each line <br>#删除每一行的开头和结尾的空格 <br>sed 's/^[ \t]*//;s/[ \t]*$//' <br>###两步走． <br># insert 5 blank spaces at beginning of each line (ake page offset) <br>#在每一行开始处插入5个空格(整页偏移) <br>sed 's/^/ /' <br>###没啥说的． <br># align all text flush right on a 79-column width <br>#右对齐，按79列宽排列所有文本 <br>sed -e :a -e 's/^.\{1,78\}$/ &amp;/;ta' # set at 78 plus 1 space <br>###这个语句好像很麻烦，不过看懂了还挺有意思．：） <br>###首先出现了几个新东东1.":" 2."&amp;". 3. "-e " 4."t"，解释一下 <br>###1.":" Label for b and t commands.(给b和t命令加注标签) <br>###2."&amp;"　表示重复整个匹配的规则表达式． <br>###3. "-e" add the script to the commands to be executed <br>### 把脚本加到命令里用以执行 <br>###4. t label If a s/// has done a successful substitution since the last <br>###input line was read and since the last t or T command, then branch to <br>###label; if label is omitted, branch to end of script. <br>###如果从读入最后一个输入行并且执行最后一个t或者T命令后，一个s///命令成功替换， <br>###那么流程分支指向label处，如果label被忽略(就是没有成功替换吧，我想),那么流程 <br>###分支指向脚本结束． <br>###回过头来看，整个sed命令行是一个循环执行的语句，每一行都要替换(78-当前行的字 <br>###符数)次,所以如果整个文件比较大，或者一行字符数比较少，做这个动作就有点吃力了． <br>###不信你试试吧，呵呵． <br># center all text in the middle of 79-column width. In method 1, <br># spaces at the beginning of the line are significant, and trailing <br># spaces are appended at the end of the line. In method 2, spaces at <br># the beginning of the line are discarded in centering the line, and <br># no trailing spaces appear at the end of lines. <br>#使所有文本居于79列宽的格式中央。在第一种方法中，每一行开头处的空格是 <br>#很重要的，最后的空格被附在行尾。第二种方法中，一行开头的空格在中心对 <br>#齐的行中被丢弃，行尾也没有原来结尾处的空格。 <br>sed -e :a -e 's/^.\{1,77\}$/ &amp; /;ta' # method 1 <br>sed -e :a -e 's/^.\{1,77\}$/ &amp;/;ta' -e 's/\(*\)1/\1/' # method 2 <br>###跟上边的差不多,当两边都加空格的时候，效率要高一些~~ <br># substitute (ind and replace)"foo" with "bar" on each line <br>#在每一行中用"bar"替换(找并替换)foo" <br>sed 's/foo/bar/' # replaces only 1st instance in a line <br># 在一行中，仅在第一次出现时替换 <br>sed 's/foo/bar/4' # replaces only 4th instance in a line <br>#在一行中，仅在第四次出现时替换 <br>sed 's/foo/bar/g' # replaces ALL instances in a line <br>#在一行中替换所有出现的值 <br>###这三个命令很简单,不多说了. <br>sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # replace the next-to-last case <br>#替换紧邻最后一个匹配出现的值 <br>###'s///---- The replacement may contain the special character &amp; to refer to that <br>###portion of the pattern space which matched, and the special escapes \1 <br>### through \9 to refer to the corresponding matching sub-expressions in the regexp. <br>###就不直接翻译了，大概意思就是replacement处可以包含&amp;代表匹配的模式空间中 <br>###的部分,特殊的\1-\9可以代表regexp中相应的"子表达式",也就是说前面regexp <br>###可以分为几个子表达式,而后边replacement中可以用\1-\9分别代表它们.这样就 <br>###增加了灵活性，便于修改sed命令. <br>###把regexp中的\去掉后，就变成(.*)foo(*foo),其中(.*)表示零个或者多个字符， <br>###这样加上后边的\1bar\2就变成了改变倒数第二个foo,而倒数第一个不变 <br>sed 's/\(*\)foo/\1bar/' # replace only the last case <br>#只替换最后一个值 <br>###比上一个简单 <br># substitute "foo" with "bar" ONLY for lines which contain "baz" <br>#在每一含有"baz"的行中用"bar"替换(查找并替换)foo" <br>sed '/baz/s/foo/bar/g' <br>### /baz/用来查找，后边的用来替换 <br># substitute "foo" with "bar" EXCEPT for lines which contain "baz" <br>#在每一不含有"baz"的行中用"bar"替换(找并替换)foo" <br>sed '/baz/!s/foo/bar/g' <br>###反其道而行之． <br># change "scarlet" or "ruby" or "puce" to "red" <br>#将"scarlet"或者"ruby"或者"puce"替换成"red" <br>sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' # most seds <br>#大多数sed可用 <br>###三步走． <br>gsed 's/scarlet\|ruby\|puce/red/g' # GNU sed only <br>#仅GNU sed可用 <br># reverse order of lines (emulates "tac") <br>#反转文章行的顺序(类似"tac" ) <br># bug/feature in HHsed v1.5 causes blank lines to be deleted <br>#??????? <br>sed '1!G;h;$!d' # method 1 <br>### <br>###首先看第一个命令1!G，这个是啥意思?"!"表示后边的命令对所有没有 <br>###被选定的行发生作用，G呢？获得保留空间(专业名词叫内存缓冲区?)中 <br>###的内容，并追加到当前模式空间的后面.1就是选定第一行.h的含义是拷贝 <br>###模式空间内容到保留空间(内存缓冲区)。那么先看 sed '1!G'什么含义 <br>###执行一下这个命令，假若文件是 <br>### $ cat test.txt <br>### 1 <br>### 2 <br>### 3 <br>### 4 <br>###那么 sed '1!G' test.txt的结果是 <br>### $ sed '1!G' test.txt <br>### 1 <br>### 2 <br>### <br>### 3 <br>### <br>### 4 <br>### <br>### $ <br>### 也就是说除了第一行,后边每行都加了空行,这是因为内存缓冲区中默认值 <br>###是空行吧。然后我们加上h,看看发生什么 <br>### $ sed '1!G;h' test.txt <br>### 1 <br>### 2 <br>### 1 <br>### 3 <br>### 2 <br>### 1 <br>### 4 <br>### 3 <br>### 2 <br>### 1 <br>### $ <br>### 空行没了，咋回事?我是这样理解的，不知道对不对，大家帮助看看：） <br>###首先要确定，执行到每一行，sed把当前处理的行存在临时的缓冲区内， <br>###称为模式空间(pattern space).一旦sed完成对模式空间中行的处理，模式 <br>###空间中的行就被送往屏幕．行被处理完成后，就被移出模式空间．．． <br>### <br>###命令执行第一行时，由于匹配了第一行，所以"!G"不起作用，只打印了 <br>###第一行的内容，然后"h"把模版块中的内容也就是第一行的内容拷贝进缓冲区， <br>###注意此时是用第一行的内容替换空行.模式空间中的内容要打印，所以出现1. <br>###执行到第二行时，打印第二行内容，而且由于不匹配"1",所以在后边"G"命令起 <br>###作用,获得了缓冲区中的第一行的内容，然后加到当前模式空间中，并打印,出现 <br>###21。然后把模式空间中的内容写入缓冲区，也就是把21写入缓冲区。执行到第三行 <br>###匹配不成功,所以缓冲区的内容应该是第二行的内容加上第一行的内容，追加到模 <br>###式空间的第三行后边：321.然后把321拷贝到缓冲区，．．．以此类推就出现了上 <br>###面的结果. <br>###我不知道这么解释对不对，但是当我把命令中的1换成2，3，4后执行，得到了我 <br>###想象的结果。还请高手指点~~ <br>###加上最后一句"$!d",那就是前面三行的结果删除，保留最后一行。这样就形成了 <br>### tac的效果啦。 <br>sed -n '1!G;h;$p' # method 2 <br>###与上边类似的，不罗嗦! <br># reverse each character on the line (emulates "rev") <br>#反转一行中每个字符的顺序(类似"rev") <br>sed '/<br>/!G;s/\(.\)\(.*<br>\)/&amp;\2\1/;//D;s/.//' <br>###这个命令真是..... <br>###我是在解释不通,所以按照我的想法来说一下吧,完全是瞎说! <br>###'/<br>/!G'是判断本行是否有换行符,如果没有执行G命令 <br>###'s/\(.\)\(.*<br>\)/&amp;\2\1/'命令是在原来行+第二个字符(或者没有)开始到换行符+第一个字符 <br>###//D命令是在模式空间删除第一行,注意执行完成后如果模式空间不为空，继续下一个 <br>###循环执行. <br>###s/.//命令是删除第一个字符 <br>###假设一行文字是 123<br><br>###那么执行后模式空间中的内容应该按下边的顺序变化 <br>### 123<br><br>### 123<br>23<br>1 <br>### 23<br>1 <br>### 23<br>13<br>21 <br>### 13<br>21 <br>### 3<br>21 <br>### 3<br>21<br>321 <br>### <br>321 <br>### 321 <br>### 我的疑问就是,为什么第一次没有执行s/.//?!如果执行了,那么就得不到结果了啊! <br>### 救~~~~命~~~啊！???????????????????????????????? <br># join pairs of lines side-by-side (like "paste") <br>#把两行合为一行(类似于"paste") <br>sed '$!N;s/<br>/ /' <br>###这个命令改成 sed 'N;s/<br>/ /'一样可以达到目的，不知前面 <br>###的$!有什么用处... <br># if a line ends with a backslash, append the next line to it <br>#如果一行以"\"结束，把下一行加在此行上 <br>sed -e :a -e '/\\$/N; s/\\<br>//; ta' <br>###循环%作，两次替换。 <br># if a line begins with an equal sign, append it to the previous line <br># and replace the "=" with a single space <br>#如果一等号开始某一行，把这一行加到前一行后边，并且用一个空格替换等号 <br>sed -e :a -e '$!N;s/<br>=/ /;ta' -e 'P;D' <br>###和上边差不多，要注意两个新的命令: <br>### P命令--Print up to the first embedded newline of the current <br>###pattern space.打印当前模式空间中第一行。 <br>###D命令--Delete up to the first embedded newline in <br>### the pattern space. Start next cycle, but skip reading from <br>###the input if there is still data in the pattern space. <br>###删除当前模式空间中第一行。开始新的循环，但是如果在模式空间中仍然 <br>###有数据，那么跳过读取输入。 <br># add commas to numeric strings, changing "1234567" to "1,234,567" <br>#给数字串加逗号，把"1234567"变为"1,234,567" <br>gsed ':a;s/\B[0-9]\{3\}\&gt;/,&amp;/;ta' # GNU sed <br>sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' # other seds <br>###(.*[0-9])表示零个或者多个字符(可能包含数字)+一个数字,而 <br>###([0-9]{3})表示三个数字,然后不停的替换,直到条件不成立,也就是没有 <br>###四个以上连续的数字出现就停止了. <br># add commas to numbers with decimal points and minus signs (NU sed) <br>#给带有小数点和负号的数字的数字加上逗号 <br>gsed ':a;s/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g;ta' <br>###没有gsed，不解释了 <br># add a blank line every 5 lines (after lines 5, 10, 15, 20, etc.) <br>#每五行后加一空行 <br>gsed '0~5G' # GNU sed only <br>sed 'n;n;n;n;G;' # other seds <br>###一大早就说过了的... <br>SELECTIVE PRINTING OF CERTAIN LINES: <br># print first 10 lines of file (emulates behavior of "head") <br>#打印一个文件的前10行(模仿动作"head") <br>sed 10q <br># print first line of file (emulates "head -1") <br>#打印一个文件的第一行(仿"head -1") <br>sed q <br>### q命令的解释Immediately quit the sed script without processing <br>###any more input, except that if auto-print is not disabled the <br>###current pattern space will be printed. <br>### 所以上边两个命令都清楚了，执行到第10行退出就打印前10行，执行第一行 <br>###就退出就打印第一行 <br># print the last 10 lines of a file (emulates "tail") <br>#打印一个文件的后10行(仿"tail") <br>sed -e :a -e '$q;N;11,$D;ba' <br>###Label b : Branch to label; if label is omitted, branch to end of script. <br>###命令D 删除模式空间内第一个 newline 字母 <br>前的资料。 <br>###命令N 把输入的下一行添加到模式空间中。 <br>### b label:分支到脚本中带有标号的地方，如果标号不存就分支到脚本的末尾 <br>### <br>waker 写到:<br>试着注一下，不知道对不对 <br>如果我们只看sed -e :a -e '$q;N;ba' <br>这个循环不停的读入下 一行直到结尾，这样整个文本就形成一个由<br>分割的链 <br>现在加上11,$D <br>sed -e :a -e '$q;N;11,$D;ba' <br>如果文本不超过10行 <br>模式空间将保留整个文本打印出来 <br>如果文本大于10行 <br>从第11行开始，在下一行加入到链中后，模式空间第一个由<br>分割的记录将被删除，这样看起来就是链头被链尾挤出整个链，总是保持10个链环，循环结束后，链中保存的就是文件的后10行,最后印出结果 <br><br># print the last 2 lines of a file (emulates "tail -2") <br>#打印一个文件的最后两行(仿"tail -2") <br>sed '$!N;$!D' <br>### 开始看不太懂，抄了CU精华一段 <br>###sed '$!N;$!D' : 对文件倒数第二行以前的行来说，N 将当前行的下一行放到模 <br>###式空间中以后，D 就将模式空间的内容删除了；到倒数第二行的时候，将最后一行 <br>###附加到倒数第二行下面，然后最后一行不执行 D ，所以文件的最后两行都保存下来了。 <br>###不知道是这段话说得有些含糊，还是我理解得有偏差，总觉得D命令解释成 <br>###"将模式空间的内容删除了"有些让人糊涂. <br>###而我是这样理解的，不知道对不对.首先说D命令是 Delete up to the first <br>###embedded newline in the pattern space.也就是说D命令是删除模式空间中 <br>###第一个换行符之前的内容，也就是删除第一行.然后D命令的解释还有一句,我认为 <br>###这句很重要: Start next cycle, but skip reading from the input if there <br>### is still data in the pattern space.开始下一个循环，但是如果模式空间中有 <br>###数据，则跳过从输入中读取数据. <br>###具体怎么工作呢? 假设文件为 <br>### $ cat test.txt <br>### 1 <br>### 2 <br>### 3 <br>### 4 <br>### 5 <br>### 那么当执行第一行时,$!N把第二行加入到模式空间中第一行后边,然后$!D把第一行 <br>###内容删除，模式空间中只剩下第二行的内容.注意,此时由于D命令开始下一个循环， <br>###所以不打印模式空间中的内容! (这个地方也是我想了半天才这么解释的，我也知道 <br>###很可能不对，欢迎拍砖，呵呵)由于D命令要求模式空间中有数据的话就跳过读取下一行， <br>###所以继续下一个循环又到了$!N，此时读入第三行加到第二行后边，....以此类推。 <br>###执行到读入第5行附加在第四行后边，然后由于$!D得不到执行，所以第4行和第5行 <br>###都被保留，命令结束，打印模式空间... <br># print the last line of a file (emulates "tail -1") <br>#打印一个文件的最后一行(仿"tail -1") <br>sed '$!d' # method 1 <br>sed -n '$p' # method 2 <br>###哈哈，终于看懂了一个，你也看懂了吧　：） <br># print only lines which match regular expression (emulates "grep") <br>#只打印匹配的一定字符的行(仿"grep") <br>sed -n '/regexp/p' # method 1 <br>sed '/regexp/!d' # method 2 <br>###明白参数-n和命令p和d就明白这两个命令． <br># print only lines which do NOT match regexp (emulates "grep -v") <br>#只打印于一定字符不匹配的行(效"grep -v") <br>sed -n '/regexp/!p' # method 1, corresponds to above <br>sed '/regexp/d' # method 2, simpler syntax <br>###和上边相反，正如注释所说． <br># print the line immediately before a regexp, but not the line <br># containing the regexp <br>#打印包含"regexp"那一行的上一行,但是不打印包含"regexp"的行. <br>sed -n '/regexp/{g;1!p;};h' <br>###在命令执行到包含"regexp"那一行的上一行时,模式空间中这行的内容被 <br>###拷贝到保留空间中．执行到包含"regexp"那一行时就打印它了. <br># print the line immediately after a regexp, but not the line <br># containing the regexp <br>#打印在"regexp"之后紧跟那一行，但是除去包含"regexp"的行. <br>sed -n '/regexp/{n;p;}' <br>###与上边类似，比上边简单． <br># print 1 line of context before and after regexp, with line number <br># indicating where the regexp occurred (imilar to "grep -A1 -B1") <br>#在"regexp"前后打印一行上下文，使其行号指示"regexp"在哪里出现( <br>#grep -A1 -B1相似) <br>sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h <br>###看上去好像挺复杂，其实倒是不难解释． <br>###假设文档是这样 <br>###$ cat test.txt <br>### 1 abc <br>### 2 cde <br>### 3 regexp <br>### 4 fgh <br>### 5 xyz <br>###命令执行到regexp前一行，引号里边的命令不执行,只执行h命令得到结果 <br>### command parttern space holdspace output <br>### 执行到前一行 2cde 2cde <br>### 执行到regexp行 "=" 3regexp 3 <br>### "x" 2cde 3regexp <br>### "1!p" 2cde 3regexp 2cde <br>### "g" 3regexp 3regexp <br>### "$N" 3regexp&nbsp;&nbsp;4fgh 3regexp <br>### "p" 3regexp&nbsp;&nbsp;4fgh 3regexp 3regexp <br>### 4fgh <br>### "D" 4fgh 3regexp <br>### "h" 4fgh 4fgh <br>### <br>### 看一下最右边的输出结果，还不错吧！ <br># grep for AAA and BBB and CCC (n any order) <br>#查找"AAA"和"BBB"和"CCC".(任意顺序) <br>sed '/AAA/!d; /BBB/!d; /CCC/!d' <br># grep for AAA and BBB and CCC (n that order) <br># 查找"AAA"和"BBB"和"CCC".(一定顺序) <br>sed '/AAA.*BBB.*CCC/!d' <br># grep for AAA or BBB or CCC (emulates "egrep") <br>#查找"AAA"或"BBB"或"CCC".(任意顺序) <br>sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # most seds <br>gsed '/AAA\|BBB\|CCC/!d' # GNU sed only <br>###上边三个没什么说的，就是查找功能呗． <br># print paragraph if it contains AAA (blank lines separate paragraphs) <br># HHsed v1.5 must insert a 'G;' after 'x;' in the next 3 scripts below <br>#如果某段包含"AAA",则打印这一段。(空行用来分隔段落) <br>#HHsed v1.5必须在'x;'之后插入一个'G;' <br>sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;' <br>###前边一部分命令用保留空间来存储整个段落内容，后边一个命令用来查找 <br># print paragraph if it contains AAA and BBB and CCC (n any order) <br>#如果某段包含"AAA"和"BBB"和"CCC",则打印这一段 <br>sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d' <br>###同上 <br># print paragraph if it contains AAA or BBB or CCC <br># 如果某段包含"AAA"或"BBB"或"CCC",则打印这一段 <br>sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d <br>gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d' # GNU sed only <br>###同上 <br># print only lines of 65 characters or longer <br>#仅打印长于65个字符的行 <br>sed -n '/^.\{65\}/p' <br>###这也没什么好说的，正则表达式的运用． <br># print only lines of less than 65 characters <br>#仅打印少于65个字符的行 <br>sed -n '/^.\{65\}/!p' # method 1, corresponds to above <br>sed '/^.\{65\}/d' # method 2, simpler syntax <br>###又没啥吧 <br># print section of file from regular expression to end of file <br>#打印从字符"regexp"开始到文件结束的部分 <br>sed -n '/regexp/,$p' <br>###还没啥，注意","的作用是选择行的范围，从包含regexp的行到最后一行 <br># print section of file based on line numbers (ines 8-12, inclusive) <br>#根据行号来打印文件的一部分(-12行，包括在内) <br>sed -n '8,12p' # method 1 <br>sed '8,12!d' # method 2 <br># print line number 52 <br>#打印第52行 <br>sed -n '52p' # method 1 <br>sed '52!d' # method 2 <br>sed '52q;d' # method 3, efficient on large files <br>###仅注意第三种方法效率比较高就行了 <br># beginning at line 3, print every 7th line <br>#从第三行开始，每7行打印一行 <br>gsed -n '3~7p' # GNU sed only <br>sed -n '3,${p;n;n;n;n;n;n;}' # other seds <br>###好像很容易理解了吧 <br># print section of file between two regular expressions (nclusive) <br>#打印文件中指定字符之间的部分(含字符在内) <br>sed -n '/Iowa/,/Montana/p' # case sensitive <br>###现在简单了吧．：） <br>SELECTIVE DELETION OF CERTAIN LINES: <br># print all of file EXCEPT section between 2 regular expressions <br>#打印除指定字符之间部分之外的全文 <br>sed '/Iowa/,/Montana/d' <br>###与上边相似的简单 <br># delete duplicate, consecutive lines from a file (emulates "uniq") <br># First line in a set of duplicate lines is kept, rest are deleted. <br>#删除文件中重复的连续的行(似于"uniq"命令) <br>#重复行中第一行保留，其他删除 <br>sed '$!N; /^\(.*\)<br>\1$/!P; D' 　 <br>###如果不是最后一行，就把下一行附加在模式空间，然后进行查找%作 <br>###"^"和"$"中间的内容如果有重复就匹配成功．如果匹配不成功就用P打印 <br>###第一行．　然后删除第一行． <br># delete duplicate, nonconsecutive lines from a file. Beware not to <br># overflow the buffer size of the hold space, or else use GNU sed. <br>#删除文件中重复的，但不连续的行。注意不要溢出保留空间的缓冲器的大小， <br>#否则使用GNU sed. <br>sed -n 'G; s/<br>/&amp;&amp;/; /^\([ -~]*<br>\).*<br>\1/d; s/<br>//; h; P' <br>###在我的linux环境执行不了，出错是sed: -e expression #1, char 34: <br>###Invalid range end.是不是所谓的溢出保留空间的大小了呢？我也不得而知． <br>###大家补充吧．!!????????????????? <br># delete the first 10 lines of a file <br>#删除一个文件中前10行 <br>sed '1,10d' <br># delete the last line of a file <br>#删除一个文件中最后1行 <br>sed '$d' <br>###与上边一个都是查找删除 <br># delete the last 2 lines of a file <br>#删除一个文件中最后2行 <br>sed 'N;$!P;$!D;$d' <br>###如果理解了sed '$!N;$!D'是如何工作的，这句话也不在话下吧！ <br># delete the last 10 lines of a file <br>#删除一个文件中后10行 <br>sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1 <br>sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2 <br>###和打印后10行相似．什么？打印后10那个没看懂? /shakehand ：） <br>###????????????????? <br># delete every 8th line <br># 每8行删除1行 <br>gsed '0~8d' # GNU sed only <br>sed 'n;n;n;n;n;n;n;d;' # other seds <br>###没说的! <br># delete ALL blank lines from a file (ame as "grep '.' ") <br>#删除文件所有空白行(似于"grep '.' ") <br>sed '/^$/d' # method 1 <br>sed '/./!d' # method 2 <br>###这两句就是告诉我们1.无内容的删除,2.有内容的保留 : ) <br># delete all CONSECUTIVE blank lines from file except the first; also <br># deletes all blank lines from top and end of file (emulates "cat -s") <br>#删除文件中除一行空白行之外的所有连续空白行，也同时删除所有从头到尾的所 <br>#有空白行(似于"cat -s") <br>sed '/./,/^$/!d' # method 1, allows 0 blanks at top, 1 at EOF <br>#方法1不允许文件顶部有空行，文件尾部可以 <br>sed '/^$/N;/<br>$/D' # method 2, allows 1 blank at top, 0 at EOF <br>#方法2不允许文件尾部有空行，文件顶部可以 <br>###两个先选择，后删除命令.不多说了. <br># delete all CONSECUTIVE blank lines from file except the first 2: <br>#删除文件中连续空行中除前两行空白行之外的所有空白行 <br>sed '/^$/N;/<br>$/N;//D' <br>###跟上边的命令相似，多了一步而已. <br># delete all leading blank lines at top of file <br>#删除文件开头部分中的所有空白行 <br>sed '/./,$!d' <br>###从有字符开始的行直到最后一行保留，其他删除. <br># delete all trailing blank lines at end of file <br>#删除文件结尾部分中的所有空白行 <br>sed -e :a -e '/^<br>*$/{$d;N;ba' -e '}' # works on all seds <br>sed -e :a -e '/^<br>*$/N;/<br>$/ba' # ditto, except for gsed 3.02* <br>###不行了要死了，还是高手说吧，我再看下去会疯的！ <br>###????????????????????????????? <br># delete the last line of each paragraph <br>#删除每个段落中最后1行 <br>sed -n '/^$/{p;h;};/./{x;/./p;}' <br>###应该是假设段落间用空行分隔 <br>###命令执行时，如果不是空行那么交换模式空间和保留空间，如果交换后 <br>###模式空间不为空，则打印模式空间中内容；如果是空行，那么打印模式空间 <br>###间中的内容,也就是打印空行...以此类推,出现结果. <br>###终于完了，下边的特殊应用没有加注，随便翻译了一下，可能不够准确，大家参考一下吧.&nbsp;&nbsp;<br>SPECIAL APPLICATIONS: <br># remove nroff overstrikes (char, backspace)from man pages. The 'echo' <br># command may need an -e switch if you use Unix System V or bash shell. <br># 从man page页里删除所有overstrikes(字符,backspace).如果使用unix系统v <br>#或者bash shell,echo命令可能需要-e参数. <br>sed "s/.`echo \\\b`//g" # double quotes required for Unix environment <br>#unix环境下需要双引号 <br>sed 's/.^H//g' # in bash/tcsh, press Ctrl-V and then Ctrl-H <br>#在bash/tcsh中，按Ctrl-V然后按Ctrl-H <br>sed 's/.\x08//g' # hex expression for sed v1.5 <br>#sed v1.5中的hex表达式 <br># get Usenet/e-mail message header <br># 获得新闻组/e-mail信息的标题部分 <br>sed '/^$/q' # deletes everything after first blank line <br># get Usenet/e-mail message body <br>#获得新闻组/e-mail信息的主体部分 <br>sed '1,/^$/d' # deletes everything up to first blank line <br># get Subject header, but remove initial "Subject: " portion <br>#获得题目的标题，但是删去开始的"Subject: "部分 <br>sed '/^Subject: */!d; s///;q' <br># get return address header <br>#获得返回的地址标题() <br>sed '/^Reply-To:/q; /^From:/h; /./d;g;q' <br># parse out the address proper. Pulls out the e-mail address by itself <br># from the 1-line return address header (ee preceding script) <br>#正确解析地址。把email地址从一行中单独提出来并返回地址头() <br>sed 's/ *(*)/; s/&gt;.*//; s/.*[: /' <br># delete leading angle bracket &amp; space from each line (nquote a message) <br>#删除每行的尖括号和空格()信息不被引用) <br>sed 's/^&gt; //' <br># remove most HTML tags (ccommodates multiple-line tags) <br>#删去大部分HTML标签(供多行标签)) <br>sed -e :a -e 's/]*&gt;//g;/zipup.bat <br>dir /b *.txt | sed "s/^\(*\).TXT/pkzip -mo \1 \1.TXT/" &gt;&gt;zipup.bat<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br><br><strong>本文来自ChinaUnix博客，如果查看原文请点：</strong><a href="http://blog.chinaunix.net/u1/44068/showart_391470.html" target=_blank><u><font color=#0000ff>http://blog.chinaunix.net/u1/44068/showart_391470.html</font></u></a> 
<img src ="http://www.cppblog.com/prayer/aggbug/126638.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-15 11:13 <a href="http://www.cppblog.com/prayer/archive/2010/09/15/126638.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sed学习笔记二--高级命令 </title><link>http://www.cppblog.com/prayer/archive/2010/09/15/126634.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 15 Sep 2010 02:33:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/15/126634.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126634.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/15/126634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126634.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126634.html</trackback:ping><description><![CDATA[<table id=content cellSpacing=10 cellPadding=0 width=650 border=0>
    <tbody>
        <tr>
            <td>
            <div><strong>版权声明：</strong>原创作品，允许转载，转载时请务必以超链接形式标明文章 <a href="http://licong.blog.51cto.com/542131/204226" target=_blank>原始出处</a> 、作者信息和本声明。否则将追究法律责任。<a href="http://licong.blog.51cto.com/542131/204226">http://licong.blog.51cto.com/542131/204226</a></div>
            </td>
        </tr>
        <tr>
            <td>
            <div><font face=-webkit-monospace><span>
            <div><span>之前写过一篇《</span><span>sed</span><span>学习笔记》</span><span><a href="http://licong.blog.51cto.com/542131/152541">http://licong.blog.51cto.com/542131/152541</a></span><span>，讲了一点</span><span>sed</span><span>入门的东西，本篇将继续介绍</span><span>sed</span><span>高级命令部分。所谓高级，主要是指这里将要提到的命令都能改变</span><span>sed</span><span>执行或者控制的流程顺序（</span><span>sed</span><span>通常都是一行被读入模式空间，并用脚本中的</span><span>sed</span><span>命令一个接一个的应用于那一行）&nbsp;</span></div>
            <div><br></div>
            <div><span>高级</span><span>sed</span><span>命令分成</span><span>3</span><span>个组：</span></div>
            <p><span><span>1、<span>&nbsp;&nbsp;&nbsp; </span></span></span><span>处理多行模式空间（</span><span>N</span><span>、</span><span>D</span><span>、</span><span>P</span><span>）。</span> </p>
            </div>
            <p><span><span>2、<span>&nbsp;&nbsp;&nbsp; </span></span></span><span>采用保持空间来保存模式空间的内容并使他们可用于后续的命令（</span><span>H</span><span>、</span><span>h</span><span>、</span><span>G</span><span>、</span><span>g</span><span>、</span><span>x</span><span>）。</span>
            <div></div>
            <p><span><span>3、<span>&nbsp;&nbsp;&nbsp; </span></span></span><span>编写使用分支和条件指令的脚本来更改控制流（：、</span><span>b</span><span>、</span><span>t</span><span>）。&nbsp;</span>
            <div></div>
            <div><span>N</span><span>命令：追加下一行</span></div>
            <div><span>多行</span><span>Next(N)</span><span>命令通过读取当前行的下一行，并把两行拼成一行来进行接下来的处理。</span></div>
            <div><span>$ cat file</span></div>
            <div><span>line 1</span></div>
            <div><span>line 2</span></div>
            <div><span>line 3</span></div>
            <div><span>line 4</span></div>
            <div><span>file</span><span>文件中的每一行后面都有一个隐藏的换行符</span><span>&#8221;\n&#8221;</span><span>，</span><span>sed</span><span>不对每行末尾的</span><span>&#8221;\n&#8221;</span><span>进行处理。</span></div>
            <div><span>$ sed N file</span></div>
            <div><span>line 1</span></div>
            <div><span>line 2</span></div>
            <div><span>line 3</span></div>
            <div><span>line 4</span></div>
            <div><span>经过</span><span>N</span><span>处理过的输出和原文件没有区别，但是本质是不一样的。这里</span><span>sed</span><span>其实认为自己打印的是</span><span>2</span><span>行，第一行为</span><span>&#8221;line 1\nline <st1:chmetcnv unitname="&#8221;" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2&#8221;</st1:chmetcnv>,</span><span>而第</span><span>2</span><span>行为</span><span>&#8221;line 3\nline <st1:chmetcnv unitname="&#8221;" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">4&#8221;</st1:chmetcnv>,</span><span>注意这里的</span><span>2</span><span>行末尾依然隐藏换行符</span><span>&#8221;\n&#8221;</span><span>，</span><span>sed</span><span>依然不处理行尾的</span><span>&#8221;\n&#8221;</span><span>，但是处理行内的</span><span>&#8221;\n&#8221;</span><span>。因为这里默认的动作是打印，所以处理行内的</span><span>&#8221;\n&#8221;</span><span>我们也看不出来。</span></div>
            <div><span>值得注意的是，处理</span><span>line 1</span><span>时，</span><span>line 2</span><span>被读入并追加到</span><span>line 1</span><span>后面，所以</span><span>line 1</span><span>处理完后不再读入</span><span>line 2</span><span>（前面已经读过了）而直接读入</span><span>line 3</span><span>进行下一个</span><span>N</span><span>命令（即读入</span><span>line 4</span><span>并追加到</span><span>line 3</span><span>后面）。</span></div>
            <div><span>上面</span><span>2</span><span>段如果不理解的话，看下面这个命令：</span></div>
            <div><span>$ sed &#8216;N;s/\n/ /g&#8217; file</span></div>
            <div><span>line 1 line 2</span></div>
            <div><span>line 3 lin3 4</span></div>
            <div><span>这个命令在原来的基础上把行内的</span><span>&#8221;\n&#8221;</span><span>替换成空格了（尽管用了全局替换标志</span><span>g</span><span>，</span><span>sed</span><span>依然不处理行尾换行符！），看明白</span><span>N</span><span>的作用了吗，单独的</span><span>N</span><span>可以创建</span><span>2</span><span>行模式空间。&nbsp;</span></div>
            <div><span>D</span><span>命令：删除多行模式空间中，直到第一个行内的</span><span>&#8221;\n&#8221;</span><span>为止的所有内容。</span></div>
            <div><span>D</span><span>命令通常位于</span><span>N</span><span>命令之后，用于处理</span><span>N</span><span>命令创建的多行模式空间。</span><span>D</span><span>命令删除多行模式空间行内第一个</span><span>&#8221;\n&#8221;</span><span>及其之前的内容后，对余下的内容（第一个行内</span><span>&#8221;\n&#8221;</span><span>之后的内容）重新从</span><span>sed</span><span>第一个命令进行处理。</span></div>
            <div><font face=宋体><br></font></div>
            <div><span>D</span><span>和</span><span>d</span><span>的相同点是，删除内容后，重新从</span><span>sed</span><span>第一个命令开始处理，这一点看来</span><span>D</span><span>和</span><span>d</span><span>都有改变</span><span>sed</span><span>执行顺序的能力；区别在于</span><span>d</span><span>删除模式空间中的所有内容，然后重新读取文本下一行从</span><span>sed</span><span>顶部进行处理，而</span><span>D</span><span>删除模式空间的一部分内容，而将模式空间剩下的内容从</span><span>sed</span><span>顶部进行处理。</span></div>
            <div><span>$ sed &#8216;N;d&#8217; file</span></div>
            <div><span>$</span></div>
            <div><span>$sed &#8216;N;D&#8217; file</span></div>
            <div><span>line 4</span></div>
            <div><span>&#8216;N;d&#8217;</span><span>每次创建</span><span>2</span><span>行模式空间，并将模式空间的内容全部删除，所以结果所有</span><span>4</span><span>行（</span><span>sed</span><span>看来是</span><span>2</span><span>行）都删除了。如果</span><span>file</span><span>有</span><span>5</span><span>行数据，则第</span><span>5</span><span>行将被打印出来，因为第</span><span>5</span><span>行执行</span><span>N</span><span>时读不到下一行了，所以</span><span>d</span><span>不执行，打印第</span><span>5</span><span>行，你可以自己试一试。</span></div>
            <div><span>&#8216;N;D&#8217;</span><span>每次创建</span><span>2</span><span>行模式空间，删除前面一行，并将模式空间的第</span><span>2</span><span>行继续执行</span><span>&#8217;N;D&#8217;,</span><span>直到最后一行</span><span>N</span><span>没内容可读，不执行</span><span>D</span><span>，而是打印最后一行。</span><span>&#8217;N;D&#8217;</span><span>实际构成了一个循环（想想</span><span>N</span><span>直接读入下一行，对</span><span>2</span><span>行进行处理，下一次对第</span><span>2</span><span>行就不处理了而是读取第</span><span>3</span><span>行处理；而加了</span><span>D</span><span>之后，先处理</span><span>2</span><span>行，再对剩下的第</span><span>2</span><span>行接着进行处理）&nbsp;</span></div>
            <div><span>P</span><span>命令：打印模式空间直到第一个</span><span>&#8221;\n&#8221;</span><span>为止的所有内容。</span></div>
            <div><span>p</span><span>（小写）是打印模式空间的所有内容，</span><span>P</span><span>（大写）是打印模式空间的一部分，这一区别和</span><span>D/d</span><span>类似。有一点要注意，不要把任何命令放在</span><span>d</span><span>或者</span><span>D</span><span>后面，因为那样该命令永远也没有执行的机会了。例如</span><span>sed &#8216;N;D;P&#8217; file</span><span>和</span><span>sed &#8216;N;D&#8217; file</span><span>是完全相同的效果。</span></div>
            <div><span>$ cat file</span></div>
            <div><span>line 1 li</span></div>
            <div><span>cong line 2</span></div>
            <div><span>line 3 licong</span></div>
            <div><span>line 4 li</span></div>
            <div><span>cong line 5</span></div>
            <div><span>我们要把分在两行的</span><span>li</span><span>和</span><span>cong</span><span>合到一行应该怎么做呢？</span></div>
            <div><span>$ sed 'N;s/li\ncong */licong\n/g;P;D' file</span></div>
            <div><span>line 1 licong</span></div>
            <div><span>line 2</span></div>
            <div><span>line 3 licong</span></div>
            <div><span>line 4 licong</span></div>
            <div><span>line 5</span></div>
            <div><span>执行这个</span><span>sed</span><span>命令的流程是这样的：</span></div>
            <div><span>一、首行文本应用</span><span>N</span><span>读取下一行，构成</span><span>2</span><span>行模式空间</span></div>
            <div><span>line 1 li\n</span></div>
            <div><span>cong line 2</span></div>
            <div><span>s</span><span>命令将</span><span>li\ncong (</span><span>注意</span><span>cong</span><span>后有一个空格</span><span>)</span><span>替换成</span><span>licong\n,</span><span>即</span></div>
            <div><span>line 1 licong</span></div>
            <div><span>line 2</span></div>
            <div><span>接着执行</span><span>P</span><span>，打印</span><span>line 1 licong</span><span>（</span><span>P</span><span>结束后两行模式空间没有改变）</span></div>
            <div><span>再对两行模式空间执行</span><span>D</span><span>，删除</span><span>line 1 licong\n,</span><span>并将剩下的</span><span>line 2</span><span>做为新的模式空间从头执行</span><span>sed</span><span>命令；</span></div>
            <div><span>二、对模式空间内容</span><span>line 2</span><span>先执行</span><span>N</span><span>，读取下一行</span><span>line 3 licong</span><span>，创建两行模式空间</span></div>
            <div><span>line 2</span></div>
            <div><span>line 3 licong</span></div>
            <div><span>这次</span><span>s</span><span>没找到匹配内容，所以执行</span><span>s</span><span>后面的</span><span>P;D</span><span>命令，重新打印、删除，进行下一轮循环；</span></div>
            <div><span>。。。</span></div>
            <div><span>三、最后一行</span><span>line 5</span><span>执行</span><span>N</span><span>没有内容可读，直接打印该行。</span></div>
            <div><span>&nbsp;</span></div>
            <div><span>h</span><span>、</span><span>H</span><span>、</span><span>g</span><span>、</span><span>G</span><span>、</span><span>x</span><span>这几个命令都是用于模式空间和保持空间转换的。这里有必要解释一下模式空间和保持空间了：</span></div>
            <div><span>模式空间——容纳当前输入行的缓冲区。</span></div>
            <div><span><span><span>除了</span><span>h/H/g/G/x</span><span>，其他所有</span><span>sed</span><span>命令都是针对模式空间的内容进行处理的！</span></span></span></div>
            <div><span>保持空间——模式空间以外的一个预留缓冲区。</span></div>
            <div><span><span><span></span><span>只有</span><span>h/H/g/G/x</span><span>命令可以访问到保持空间的内容，并用于与模式空间内容的转换。</span></span></span></div>
            <div><br></div>
            <div><span>h</span><span>：将模式空间的内容复制到保持空间，类似与重定向符号</span><span>&gt;</span><span>，会覆盖原由保持空间内容</span></div>
            <div><span>H</span><span>：将模式空间的内容追加到保持空间，类似与追加重定向</span><span>&gt;&gt;</span><span>，追加到保持空间的尾行下</span></div>
            <div><span>g</span><span>：类似</span><span>h</span><span>，将保持空间的内容复制到模式空间</span></div>
            <div><span>G</span><span>：类似</span><span>H</span><span>，将保持空间的内容追加到模式空间</span></div>
            <div><span>x</span><span>：交换模式空间与保持空间中的内容&nbsp;</span></div>
            <div><br></div>
            <div>$ cat file</div>
            <div><span>1</span></div>
            <div><span>2</span></div>
            <div><span>11</span></div>
            <div><span>22</span></div>
            <div><span>$ sed &#8216;/1/{h;d};/2/G&#8217; file</span></div>
            <div><span>2</span></div>
            <div><span>1</span></div>
            <div><span>22</span></div>
            <div><span>11</span></div>
            <div><span>这个</span><span>sed</span><span>命令完成了反转的功能，我们来看看是怎么实现的：</span></div>
            <div><span>一、</span><span>/1/{h;d}</span><span>命令搜索模式空间包含</span><span>1</span><span>的行然后先后执行</span><span>h</span><span>和</span><span>d</span><span>命令。结果首行</span><span>1</span><span>将被应用，<span><span>h</span><span>把该行（内容为</span><span>1</span><span>）复制到保持空间，此时模式空间和保持空间中的内容为：</span></span></span></div>
            <div><span>模式空间：</span><span>1</span></div>
            <div><span>保持空间：</span><span>1</span></div>
            <div><span>接着执行</span><span>d</span><span>，</span><span>d</span><span>不能访问保持空间，只处理模式空间的内容，将模式空间的内容删除，此时：</span></div>
            <div><span>模式空间：</span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>（空，没有内容）</span></div>
            <div><span>保持空间：</span><span>1</span></div>
            <div><span>二、</span><span>d</span><span>命令执行完之后，执行</span><span>/2/G</span><span>，即在模式空间搜索包含</span><span>2</span><span>的行进行</span><span>G</span><span>处理，而此时模式空间无内容，所以不做任何操作。</span></div>
            <div><span>三、读取下一行文本到模式空间，继续执行</span><span>&#8217;/1/{h;d};/2/G&#8217;</span><span>。下一行文本的内容是</span><span>2</span><span>，此时：</span></div>
            <div><span>模式空间：</span><span>2</span></div>
            <div><span>保持空间：</span><span>1</span></div>
            <div><span>与步骤二的道理相同，</span><span>h</span><span>、</span><span>d</span><span>得不到执行（因为模式可空间没找到包含</span><span>1</span><span>的行）；而</span><span>&#8217;/2/G&#8217;</span><span>将被执行，将保持空间的内容追加到模式空间后面，此时：</span></div>
            <div><span>模式空间：</span><span>2</span></div>
            <div><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span> </span>1</span></div>
            <div><span>保持空间：</span><span>1</span></div>
            <div><span>这一步完成以后，模式空间的内容将被</span><span>sed</span><span>默认地打印出来（如果有</span><span>-n</span><span>参数才不打印），于是前两行处理完之后，将输出：</span></div>
            <div><span>2</span></div>
            <div><span>1</span></div>
            <div><br></div>
            <div><span>同理，后两行处理完之后，将输出：</span></div>
            <div><span>22</span></div>
            <div><span>11</span></div>
            <div><span>于是，我们看到了最后的结果：</span></div>
            <div><span>2</span></div>
            <div><span>1</span></div>
            <div><span>22</span></div>
            <div><span>11&nbsp;</span></div>
            <div><span>这个最简单的例子有很多地方值得挖掘，我们就来看看最重要的几点。</span></div>
            <p><span><span>1、&nbsp;</span></span><span>当</span><span>sed</span><span>后面带有一个以上的命令时，它的处理顺序是这样的：</span>
            <div></div>
            <p><span><span><span>一次读入一行到模式空间，然后将所有的命令应用于该行；而不是一次将一个命令作用与所有行；</span></span></span>
            <div></div>
            <p><span><span>2、&nbsp;</span></span><span>当某个条件后面有</span><span>{}</span><span>时，</span><span>{}</span><span>里面的命令依次作用于满足该条件的行；</span>
            <div></div>
            <p><span><span><span><span>3、&nbsp;</span></span><span>h/H/g/G</span><span>命令操作缓冲区时，都会在目的缓冲区后加一个换行（即使该缓冲区无内容），然后复制或追加源缓冲区内容在该换行符之后；</span></span></span>
            <div></div>
            <p><span><span>4、&nbsp;</span></span><span>没有使用</span><span>-n</span><span>参数时，当一行执行完所有命令后，</span><span>sed</span><span>会默认打印最终模式空间中的内容；</span>
            <div></div>
            <p><span><span><span>如果使用</span><span>-n</span><span>参数，只有应用了</span><span>p/P</span><span>命令的模式空间内容才会被打印出来。</span></span></span>
            <div></div>
            <p><font face=宋体><br></font>
            <div></div>
            <div><span>x</span><span>命令暂不举例，我们来看看最后一组高级命令（：、</span><span>b</span><span>、</span><span>t</span><span>）</span></div>
            <div><span>分支（</span><span>b</span><span>）和测试（</span><span>t</span><span>）命令几乎可以任意改变</span><span>sed</span><span>命令的执行顺序，他们都将</span><span>sed</span><span>转移到包含标签的行，如果没有指定标签，则将转移到命令末尾。</span><span>b</span><span>用于无条件的转移（即一碰到</span><span>b</span><span>立刻转移）；</span><span>t</span><span>用于有条件转移，只有当替换命令改变当前行时才会执行。&nbsp;</span></div>
            <div><span>标签定义：</span></div>
            <div><span>:lable</span></div>
            <div><span>lable</span><span>可以随便用什么名字，自己能方便看明白就行；冒号和标签之间不允许有空格，</span><span>lable</span><span>后面如果有空格将被认为是</span><span>lable</span><span>的一部分（不建议在</span><span>lable</span><span>后面带空格）</span></div>
            <div><span>b</span><span>和</span><span>t</span><span>的用法：</span></div>
            <div><span>[address]b [lable]</span></div>
            <div><span>[address]t [lable]</span></div>
            <div><span>b/t</span><span>和</span><span>lable</span><span>之间有空格，但</span><span>lable</span><span>后面不要插入空格。</span></div>
            <div><span>举例：</span></div>
            <div><span>$ cat file</span></div>
            <div><span>line 1 li</span></div>
            <div><span>cong line 2</span></div>
            <div><span>line 3 licong</span></div>
            <div><span>line 4 li</span></div>
            <div><span>cong line 5&nbsp;</span></div>
            <div><br></div>
            <div><span>$ sed -n '$!{/licong/!{h;N;D}</span></div>
            <div><span>x;G;N;p;b</span></div>
            <div><span>}</span></div>
            <div><span>${/licong/{x;G;p}}' file</span></div>
            <div><span><span>cong line 2</span></span></div>
            <div><span><span>line 3 licong</span></span></div>
            <div><font face=Tahoma color=#313131><span>
            <div><span>line 4 li&nbsp;</span></div>
            </span></font></div>
            <div><span>这个</span><span>sed</span><span>命令的功能是寻找包含字符串</span><span>licong</span><span>的行，并打印该行及其前后一行。这个命令并不完善，它不能很好的处理第一行匹配的情况，加入该功能命令会变得更复杂。我们来解释一下上面的结果是怎么来的。</span></div>
            <div><span>一、</span><span>sed -n '$!{/licong/!{h;N;D}</span></div>
            <div><span>x;G;N;p;b</span></div>
            <div><span>}&nbsp;</span></div>
            <div><span>对除末行以外的所有行</span><span>($!</span><span>的作用</span><span>)</span><span>，执行</span><span>/licong/!{h;N;D}</span><span>；</span><span>x;G;N;p;b</span></div>
            <div><span>二、</span><span>/licong/!{h;N;D}</span></div>
            <div><span>对不包含字符串</span><span>licong</span><span>的行依次执行</span><span>h</span><span>；</span><span>N</span><span>；</span><span>D</span><span>，第一行</span><span>line 1 li</span><span>不包含</span><span>licong</span><span>，于是执行：</span></div>
            <div><span>把该行复制到保持空间，读取追加下一行，此时</span></div>
            <div><span>模式空间：</span><span>line 1 li</span></div>
            <div><span>cong line 2</span></div>
            <div><span>保持空间：</span><span>line 1 li</span></div>
            <div><span>再对模式空间执行</span><span>D</span><span>，并接着从头处理新的模式空间，此时</span></div>
            <div><span>模式空间：</span><span>cong line 2</span></div>
            <div><span>保持空间：</span><span>line 1 li</span></div>
            <div><span>三、从头对模式空间的内容</span><span>cong line 2</span><span>执行</span><span>$!{/licong/!{h;N;D}</span><span>，此时的模式空间依然不包含</span><span>licong</span><span>，所以进行一二两步同样的操作，结束后：</span></div>
            <div><span>模式空间：</span><span>line 3 licong</span></div>
            <div><span>保持空间：</span><span>cong line 2</span></div>
            <div><span>四、再从头对新的模式空间</span><span>line 3 licong</span><span>执行</span><span>/licong/!{h;N;D}</span><span>；</span><span>x;G;N;p;b</span><span>。因为此时的模式空间包含</span><span>licong</span><span>，所以不执行</span><span>h;N;D</span><span>了，而是执行</span><span>x;G;N;p;b</span><span>。</span><span>x</span><span>用与交换模式空间和保持空间的内容，交换的结果是：</span></div>
            <div><font face=宋体 color=#313131><br></font></div>
            <div><span>模式空间：</span><span>cong line 2</span></div>
            <div><span>保持空间：</span><span>line 3 licong</span></div>
            <div><br></div>
            <div><span>接下来执行</span><span>G</span><span>，将保持空间的内容追加到模式空间之后：</span></div>
            <div><font face=宋体><br></font></div>
            <div><span>&nbsp;</span><span>模式空间：</span><span>cong line 2</span></div>
            <div><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>line 3 licong</span></div>
            <div><span>保持空间：</span><span>line 3 licong</span></div>
            <div><br></div>
            <div><span>再执行</span><span>N</span><span>，将下一行读取追加到模式空间之后：</span></div>
            <div><font face=宋体 color=#313131><br></font></div>
            <div><span>&nbsp;</span><span>模式空间：</span><span>cong line 2</span></div>
            <div><span>line 3 licong</span></div>
            <div><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>line 4 li</span></div>
            <div><span>保持空间：</span><span>line 3 licong</span></div>
            <div><span>再执行</span><span>p</span><span>，打印模式空间的内容：</span></div>
            <div><span>cong line 2</span></div>
            <div><span><span>&nbsp;&nbsp;&nbsp;&nbsp;</span>line 3 licong</span></div>
            <div><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>line 4 li<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>（这就是我们看到的结果）</span></div>
            <div><span>之后还有一个</span><span>b</span><span>，就是跳过</span><span>b</span><span>后面的命令，再读下一行。命令最后一部分</span><span>${/licong/{x;G;p}}</span><span>是用来处理最后一行的，如果最后一行包含</span><span>licong</span><span>则打印该行很上面一行（而不打印下一行，因为没有</span><span>N</span><span>命令）</span></div>
            <div><font face=宋体 color=#313131><br></font></div>
            <div><span>到此，</span><span>sed</span><span>的高级命令就介绍完了。《</span><span>sed&amp;awk</span><span>》第二版有一句话：&#8220;一旦你理解了这里所给出的命令，那么就可以认为自己是真正的</span><span>sed</span><span>的主人了。&#8221;</span></div>
            <div><span>再总结一下</span><span>sed</span><span>所有的功能，总的来说还是替换命令</span><span>&#8217;[address]s/source/replace/flag&#8217;</span><span>最常用，而高级命令则用于完成复杂的任务；还有</span><span>sed</span><span>的</span><span>-n</span><span>（抑制默认输出）、</span><span>-i</span><span>（更改原文件）等参数也很常用。&nbsp;</span></div>
            <div><span>就写到这里吧，等待拍砖了。。。</span></div>
            </span></font>
            <p>本文出自 &#8220;<a href="http://licong.blog.51cto.com/">licong</a>&#8221; 博客，请务必保留此出处<a href="http://licong.blog.51cto.com/542131/204226">http://licong.blog.51cto.com/542131/204226</a></p>
            <a href="http://licong.blog.51cto.com/542131/204226">本文出自 51CTO.COM技术博客</a></td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/prayer/aggbug/126634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-15 10:33 <a href="http://www.cppblog.com/prayer/archive/2010/09/15/126634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用sed命令如何能把一个匹配模式替换为换行符</title><link>http://www.cppblog.com/prayer/archive/2010/09/15/126632.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 15 Sep 2010 02:15:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/15/126632.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126632.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/15/126632.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126632.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126632.html</trackback:ping><description><![CDATA[将空格替换为换行符。<br>两种犯方法<br>1使用cutr V+ctrl J代替换行符<br>sed 's/ /\^J/g'<br>2 直接使用换行符<br>s/ /\<br>/g 
<img src ="http://www.cppblog.com/prayer/aggbug/126632.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-15 10:15 <a href="http://www.cppblog.com/prayer/archive/2010/09/15/126632.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用shell提供的命令行编辑功能, 选择set -o vi 还是 set -o emacs </title><link>http://www.cppblog.com/prayer/archive/2010/09/01/125489.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 01 Sep 2010 01:36:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/01/125489.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/125489.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/01/125489.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/125489.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/125489.html</trackback:ping><description><![CDATA[<p>今天登入系统， 敲了N多命令后，习惯性的用向上的方向键来找寻历史命令，突然看到了这个：</p>
<p>&nbsp; $^[[A^[[A^[[A&nbsp; </p>
<p>按删除键，出来的是这个：</p>
<p>&nbsp; $ ^H^H^H^H^H^H^H&nbsp; </p>
<p>只能用 Ctrl+BackSpace 才能删除光标左边的内容...用的那个不习惯啊~~~！！！ - -b</p>
<p>后来问到 Wells ，原来只需要做一个小小的设定，在Console中启用：</p>
<p>&nbsp; $set -o emasc&nbsp; </p>
<p>原因后来上网查了一下，暂且引用一下《FreeBSD使用大全》中的一段内容：</p>
<p>-----------------------------------------------------------------------------------------------</p>
<p>配置用戶shell<br>　　事實上sh與csh，并不是普通用戶的最佳選擇，因為這兩個shell在易用性方面做的不夠好，例如命令行編 輯功能不強、不能利用熱鍵重復執行命令等。較新的shell，如bash和tcsh都具有這些方便用戶使用的功能，但 必須安裝了這些shell程序之后，才能更改普通用戶的shell設置以使用這些shell程序。更改用戶的shell 可以使用pw、vipw或chsh。</p>
<p>　　這兩個shell分別遵照sh和csh的風格，因此喜好csh風格的可以選擇tcsh，而喜歡sh風格的選擇 bash。除了這兩種shell之外，還有ksh、zsh等shell可供選擇。如果對兩種shell沒有偏好，可以 選擇bash，它是一個GNU軟件，比標准sh功能強大的多。</p>
<p>　　使用了這兩些增強型shell之后，用戶就可以使用shell提供的命令行編輯功能。按照習慣的不同，可以選 擇vi風格的編輯方式或emacs風格的方式，缺省為emacs方式，這種方式使用方向鍵來回溯執行過的命令，并進行 修改，而vi風格使用字母命令作編輯鍵，例如使用h、j、k、l四個鍵來移動光標，vi風格的好處是不使用基本鍵盤之 外的控制鍵，因而可以適用于任何終端設備，并且進行編輯時手不需離開基本鍵盤，熟練操作之后最為快捷。emacs風格 比起vi風格更適合從個人計算機轉向Unix的使用者的習慣。bash, ksh ,zsh下使用下面的命令在emacs 風格和vi風格切換：</p>
<p>　　bash$ set -o emacs </p>
<p>　　bash$ set -o vi </p>
<p>　　tcsh中使用不同的命令：</p>
<p>　　% bind emacs</p>
<p>　　% bind vi</p>
<p>　　還可以為常用的命令設置別名，簡化用戶輸入，例如：</p>
<p>　　bash$ alias ec=&#8221;echo This is a alias&#8221;</p>
<p>　　bash$ ec</p>
<p>　　This is a alias</p>
<p>　　shell用于方便用戶操作的另一項能力是自動補全命令或文件名的功能，因為FreeBSD下的文件名可能很 長，將它們全部輸入比較麻煩。事實上可以輸入部分名字，然后按Tab鍵（在vi風格下是連續兩次按Esc鍵），shell 將自動補全文件名的剩余部分。如果已經輸入的這部分名字不能確定具體的命令或文件，那么shell只將能確定的部 分補上，然后響鈴通知使用者繼續輸入以明確具體的文件。</p>
<p>　　事實上即使在基本的sh或csh下，也可以使用 &#8220;*&#8221; 等特殊字符，用模式匹配的方式來簡化輸入。</p>
<p>　　bash$ cd /usr/loca*</p>
<p>　　bash$ pwd</p>
<p>　　/usr/local</p>
<p>　　Unix中的多數程序都具備模式匹配的處理能力，而shell的模式匹配功能最為常用。shell可以使用這 些特殊模式來配置多個文件，達到簡化操作的目的。如果要熟練掌握Unix，必須掌握模式匹配。</p>
<p>　　當試圖在bash下輸入漢字的時候，除了必須設置終端屬性能接受8位字符之外（執行stty pass8命令 ），還需要設置bash的輸入輸出轉換，可以在登錄腳本.profile文件中包括以下設置：</p>
<p>　　bind 'set convert-meta off'</p>
<p>　　bind 'set meta-flag on'</p>
<p>　　bind 'set output-meta on'</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/chenguoda/archive/2008/06/08/2524292.aspx">http://blog.csdn.net/chenguoda/archive/2008/06/08/2524292.aspx</a></p>
<img src ="http://www.cppblog.com/prayer/aggbug/125489.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-01 09:36 <a href="http://www.cppblog.com/prayer/archive/2010/09/01/125489.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>awk中使用shell的环境变量</title><link>http://www.cppblog.com/prayer/archive/2010/08/26/124862.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 26 Aug 2010 10:26:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/08/26/124862.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/124862.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/08/26/124862.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/124862.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/124862.html</trackback:ping><description><![CDATA[<strong>一:"'$var'"<br><br></strong>这种写法大家无需改变用'括起awk程序的习惯,是老外常用的写法.如:<br><br>var="test"<br><br>awk 'BEGIN{print "'$var'"}'<br><br>这种写法其实际是双括号变为单括号的常量,传递给了awk.<br><br>如果var中含空格,为了shell不把空格作为分格符,便应该如下使用:<br><br>var="this is a test"<br><br>awk 'BEGIN{print "'"$var"'"}'<br><br><strong>二:'"$var"'</strong><br><br>这种写法与上一种类似.如果变量含空格,则变为'""$var""'较为可靠.<br><br><strong>三.把括起awk程序的''变为"",使用"$var"</strong><br><br>如:<br><br>$var="this is a test"<br><br>awk 'BEGIN{print "$var"}"<br><br>这是因为在""里$是特殊字符,而在''里$是普通字符.<br><br><strong>四:export 变量,使用ENVIRON["var"]形式,</strong><br><br>如:<br><br>$var="this is a test";export $var<br><br>awk 'BEGIN{print ENVIRON["var"]}'<br><br><strong>五:当然也可以使用-v选项</strong><br><br>如:<br><br>$var="this is a test"<br><br>awk -vnvar="$var" '{print nvar}'<br><br>这样便把系统变量定义成了awk变量.
<img src ="http://www.cppblog.com/prayer/aggbug/124862.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-08-26 18:26 <a href="http://www.cppblog.com/prayer/archive/2010/08/26/124862.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>把shell变量传给awk有3种方式</title><link>http://www.cppblog.com/prayer/archive/2010/08/26/124860.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 26 Aug 2010 10:16:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/08/26/124860.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/124860.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/08/26/124860.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/124860.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/124860.html</trackback:ping><description><![CDATA[<div>1.利用shell cmdline的特性</div>
<div>A=123</div>
<div>awk '/^'"$A"'/ { print $2 }'</div>
<div>&nbsp;</div>
<div>上面的cmdline中，shell把'/^'"$A"'/ { print $2 }'作为awk的第一个参数，这个'/^'"$A"'/ { print $2 }'可以分为3小块</div>
<div>（1）'/^'：因为/^被单引号引起来，所以shell传这个小部分给awk时候，传的是：/^</div>
<div>（2）"$A"：因为$A是被双引号引起，所以shell传这个小部分给awk时候，先把$A,做给&#8220;变量替换&#8221;，所以传的是：123</div>
<div>（3）'/ { print $2 }'：因为/ { print $2 }被单引起来，所以传的是：/ { print $2 }</div>
<div>&nbsp;</div>
<div>这3个小部分做为一个参数传给awk，合计3个小部分，那么传的就是</div>
<div>/^123/ { print $2 }</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>2.使用-v参数</div>
<div>A=123</div>
<div>awk -v B="$A" '/^B/ { print $2 }'</div>
<div>&nbsp;</div>
<div>3.pass variable settings into awk as "fake file names"</div>
<div>awk '/^B/ { print $2 }' B="$A"</div>
<img src ="http://www.cppblog.com/prayer/aggbug/124860.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-08-26 18:16 <a href="http://www.cppblog.com/prayer/archive/2010/08/26/124860.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>awk的next使用 </title><link>http://www.cppblog.com/prayer/archive/2010/08/26/124779.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 26 Aug 2010 02:35:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/08/26/124779.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/124779.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/08/26/124779.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/124779.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/124779.html</trackback:ping><description><![CDATA[<div class=specialmsg>
<table cellSpacing=0 cellPadding=0>
    <tbody>
        <tr>
            <td class=t_msgfont id=postmessage_11083743>next&nbsp;&nbsp;可以简单理解为跳过后面的代码，如果next被执行，那么它后面的代码就都不会被执行了。</td>
        </tr>
    </tbody>
</table>
</div>
<img src ="http://www.cppblog.com/prayer/aggbug/124779.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-08-26 10:35 <a href="http://www.cppblog.com/prayer/archive/2010/08/26/124779.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AWK高级编程</title><link>http://www.cppblog.com/prayer/archive/2010/08/26/124778.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 26 Aug 2010 02:26:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/08/26/124778.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/124778.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/08/26/124778.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/124778.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/124778.html</trackback:ping><description><![CDATA[<p>1. 程序元素 </p>
<p>一个awk 程序是一对以模式(pattern) 与大括号框起来的操作(action) 组合而成的，或许，还会加上实现操作细节的函数(function ) 。针对每个匹配于输人数据的模式，操作会被执行，且所有模式都会针对每条输人记录而检查。模式或操作可省略其中一个。如果模式省略，则操作将被应用到每条输人记录; 如果操作省略，则默认操作为打印匹配之记录在标准输出上。以下是传统awk 程序的配置: </p>
<p>pattern&nbsp; {action} 如模式匹配，则执行操作 </p>
<p>pattern&nbsp; {action} 如模式匹配，则打印记录 </p>
<p>虽然，模式多半是数字或字符串表达式，不过awk 以保留字BEGIN 与END 提供两种特殊模式。 </p>
<p>与BEG 工N 关联的操作只会执行一次，在任何命令行文件或一般命令行赋值被处理之前，但是在任何开头的一V 选项指定已经完成之后。 </p>
<p>END 操作也是只执行一次，用于所有输入数据已被处理完之后。它多半用于产生摘要报告，或是执行清除操作。 </p>
<p>BEGIN 与END 模式可以是任意顺序，可以存在于awk 程序内的任何位置。不过，为了方便，我们通常将BEGIN 模式放在程序的第一个位置，而将END 模式放在最后。 </p>
<p>2. 注释与空白 </p>
<p>awk 里的注释是从# 开始到该行结束，就像在Shell 里那样。空行等同于空的注释。 </p>
<p>3. 字符串与字符串表达式 </p>
<p>awk 字符串包含零至多个字符，且在字符串的长度上没有限制，视可用内存而定。 </p>
<p>字符串的比较，用的是传统的关系运算符：==( 相等) 、!=( 不等) 、&lt;( 小于) 、&lt;=( 小于等于) 、&gt;( 大于) ，以及&gt;=( 大于等于》。比较后返回l 为真，0 为假。比较不同长度的字符串，且其中一个字符串为另一个的初始子字符串时，较短的会定义为小于较长的那个，因此，&#8220;A &#8221;&lt; &#8220;AA &#8221;的值为真。 </p>
<p>awk 并无特殊的字符串接续运算符。也就是说，两个连续字符串，会自动地连接在一起。以下每一组赋值设置标量变量。为相同的具有四个字符的字符串: </p>
<p>s = &#8220;ABCD &#8221; </p>
<p>s = &#8220;AB &#8221;&#8220;CD &#8221; </p>
<p>s = &#8220;A &#8221;&#8220;B &#8221;&#8220;CD &#8221; </p>
<p>s = &#8220;A &#8221;&#8220;B &#8221;&#8220;C &#8221;&#8220;D &#8221; </p>
<p>字符串不需要是常数，如果我们继续上述的赋值: </p>
<p>t= s s s </p>
<p>则t 的值为&#8220;ABCDABCDABCD &#8220;。. </p>
<p>&nbsp; </p>
<p>将数字转换为字符串，通过数字连接空字符串即可 </p>
<p>n =123 ， </p>
<p>接着是： </p>
<p>s = &#8220;&#8220; n ，把值&#8220;123 &#8221;赋给s 。 </p>
<p>&nbsp; </p>
<p>awk 功能强大的地方大多来自于它对正则表达式的支持。有两个运算符：~( 匹配) 与!~( 不匹配) 让awk 更容易使用正则表达式：&#8221;ABC &#8221;~ &#8221;^[A-Z]+$ &#8220;，结果为真。 </p>
<p>4. 数值与数值表达式 </p>
<p>所有awk 里的数字，都以双精确度的浮点值表示。浮点数可以包含一个末端以字母e( 或E) 所表示的10 次方指数以及可选地带正负号的一个整数。举例来说:0.03125, 3.125e-2, 3125e-5 与0.003125E1 ，同样都是表示1/32 。因为awk 里所有算术都是浮点算术。 </p>
<p>awk 并没有提供字符串转数字的函数，不过awk 的做法很简单：只要加个零到字符串里，例如：s="123" ，接着是n=0+s ，便将数字123 赋值给n 了。 </p>
<p>5. awk 的数值运算符 </p>
<p>表9 一：awk 的数值运算符( 优先级由大到小排列) </p>
<p>运算符&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明 </p>
<p>&nbsp; ++ --&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 增加与减少( 前置或后置) </p>
<p>&nbsp; ^ **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 指数( 右结合性) </p>
<p>&nbsp; ! + -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 非、一元(unary) 加号、一元减号 </p>
<p>&nbsp; * / %&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 乘、除、余数 </p>
<p>&nbsp; + -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 加、减 </p>
<p>&lt; &lt;= == != &gt; &gt;=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比较 </p>
<p>&amp;&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 逻辑AND( 简写) </p>
<p>||&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 逻辑OR( 简写) </p>
<p>?:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 三元条件式 </p>
<p>= += -= *= /= %= ^= **=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 赋值( 右结合性) </p>
<p>6. 标量变量 </p>
<p>保存单一值的变量叫做标量变量。 </p>
<p>a wk 的变量名称必须以ACSII 字母或下划线开始，然后选择性地接上字母、下划线及字。因此，变量名称要匹配正则表达式[A-Za-z-][A-Za-z_0-9]* 。变量名称在实际上并没有长度的限制。awk 的变量名称是与大小写有关的:foo, Fo 。与FOO 是完全不同的三个名称。一般使用上以及建议用法是: 养成习惯，将局部变量全设为小写、全局变量第一个字母为大写，而内建变量则全是大写。 </p>
<p>7. 数组变量 </p>
<p>awk 允许在数组名称之后，以方括号将任意数字或字符串表达式 括起来作为索引。例如: </p>
<p>telephone["Alice"]= &#8220;555-0134" </p>
<p>telephone["Bob"]= &#8220;555-0135" </p>
<p>telephone["Carol&#8221;]= &#8220;555-0136" </p>
<p>telephone["Don"]= &#8220;555-0141" </p>
<p>以任意值为索引的数组，称之为关联数组，因为它们的名称与值是相关联的。重要的是，awk 将其应用于数组中，允许查找( find ) 、插入(insert ) 以及删除( remove) 等操作，在一定的时间内完成，与存储多少项目无关。 </p>
<p>一个变量不能同时用作标量变量和数组变量。当你应用delet 。语句删除数组的元素 </p>
<p>(element] 的时候，不会删除它的名称。因此。像这样的代码: </p>
<p>x[1]=3 </p>
<p>delete x </p>
<p>x=789 </p>
<p>会引发awk 发出提示，告诉你不可以给数组名称赋值. </p>
<p>8. 命令行参数 </p>
<p>awk 通过内建变量ARGC( 参数计数) 与ARGV( 参数向量，或参数值) ，让命令行参数 </p>
<p>可用。下面简短的程序说明其用法; </p>
<p>[root@local~]#cat showargs.awk </p>
<p>BEGIN{ </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &#8221;ARGC= &#8221;，ARGC </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (k=0;k&lt;ARGC; k++) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "ARGV[&#8221;k&#8221;]=[&#8221;ARGV[k] &#8220; </p>
<p>} </p>
<p>再来看看将它用在一般awk 命令行上，会产生什么样的结果: </p>
<p>[root@local~]# awk -v One=1 -v Two=2 -f showargs.awk Three=3 file1 Four=4 filet2 file3 </p>
<p>ARGC=6 </p>
<p>ARGV[0]=[awk] </p>
<p>ARGV[1]=[Three=3] </p>
<p>ARGV[2]=[file1] </p>
<p>ARGV[3]=[Four=4] </p>
<p>ARGV[4]=[file2] </p>
<p>ARGV[5]=[file3] </p>
<p>9. 环境变量 </p>
<p>awk 提供访问内建数组ENV 工RON 中所有的环境变量: </p>
<p>[root@local~]#awk 'BEGIN {print ENVIRON["HOME"];print ENVIRON["USER]} &#8216; </p>
<p>/home/Jones </p>
<p>hones </p>
<p>通常你应将ENVIRON 看成是一个只读数组。 </p>
<p>10. 模式 </p>
<p>模式由字符串与 / 或数值表达式构建而成。常用的模式如下： </p>
<p>NF==0&nbsp;&nbsp;&nbsp; 选定空记录 </p>
<p>NF&gt;3&nbsp;&nbsp;&nbsp;&nbsp; 选定拥有三个字段以上的记录 </p>
<p>NR&lt;5&nbsp;&nbsp;&nbsp; 选定第 1 到第 4 条记录 </p>
<p>(FNR==3)&amp;&amp;(FILENAME~/[.] [ch]$/) 来源于 C 源文件中选定记录 3 </p>
<p>$1~/Jones/&nbsp;&nbsp; 选定字段 1 里有 . &#8221; jones &#8220;的记录 </p>
<p>/[Xx][Mm][Ll]/ 选定含有&#8216; 'XML' 。的记录，并忽略大小写差异 </p>
<p>$0~/[Xx][Mm][Ll]/ 同上 </p>
<p>11. 操作 </p>
<p>以最简单的形式来说，纯print 意指在标准输出上，打印当前的输入记录($0) ，接着是输出记录分隔字符)ORS 的值，默认为单一换行字符。因此，下面这些程序所做的全是相同的操作: </p>
<p>1&nbsp;&nbsp;&nbsp; 模式为真，默认操作为打印 </p>
<p>NR&gt;0 {print} 有记录时打印( 恒为真) </p>
<p>1&nbsp;&nbsp;&nbsp; {print}&nbsp; 模式为真。则打印，这是默认值 </p>
<p>{print}&nbsp; 无模式则视为真，明确的打印，这是默认值 </p>
<p>{print $0}&nbsp; 相同，但打印明确的值 </p>
<p>下面的例子已经是完整的awk 程序。在每一个中，我们都只显示前三个输入字段，并通过省略选定模式，选定所有的记录。awk 程序语句以分号分隔，而且我们会使用些略微不同的操作代码，以修改输出字段分隔字符: </p>
<p>[root@local~]#echo &#8216;one two three four'| awk &#8216;{print $1,$2,$3}&#8217; </p>
<p>one two three </p>
<p>[root@local~]#echo &#8216;one two three four'| awk &#8216;{OFS=&#8221;&#8230;&#8221;;print $1,$2,$3}&#8217; </p>
<p>one&#8230;two&#8230;three </p>
<p>[root@local~]#echo &#8216;one two three four'| awk &#8216;{OFS=&#8221;\n&#8221;;print $1,$2,$3}&#8217; </p>
<p>one </p>
<p>two </p>
<p>three </p>
<p>&nbsp; </p>
<p>改变输出字段分隔字符而没有指定任何字段，不会改变$0: </p>
<p>[root@local~]#echo &#8216;one two three four'| awk &#8216;{OFS=&#8221;\n&#8221;;print $0}&#8217; </p>
<p>one two three four </p>
<p>不过，如果我们更改输出字段分隔字符，并指定至少一个字段( 即使我们未变更其值) ， </p>
<p>强制以新的字段分隔字符重新组合记录，则结果为: </p>
<p>[root@local~]#echo &#8216;one two three four'| awk &#8216;{OFS=&#8221;\n&#8221;;$1=$1;print $0}&#8217; </p>
<p>one </p>
<p>two </p>
<p>three </p>
<p>four </p>
<p>&nbsp; </p>
<p>12. 在awk 中的单行程序 </p>
<p>1.UNIX 单词计数程序wc; </p>
<p>[root@local~]#awk &#8216;{C+=length($0)+1;w+=NF} END {print NR, W, C}&#8217; </p>
<p>&nbsp; </p>
<p>2. 撇开NUL 字符问题，awk 其实可以轻松取代cat ，下面这两个例子会产生相同输出: </p>
<p>[root@local~]# cat*.xml </p>
<p>[root@local~]# awk 1*.xml </p>
<p>&nbsp; </p>
<p>3. 要将原始数据值及它们的对数打印为单栏的数据文件，可使用: </p>
<p>[root@local~]# awk &#8216;{print $1, log($1)}&#8217;file(s) </p>
<p>&nbsp; </p>
<p>4. 在以空白分隔字段的表格中，报告第n 栏的和: </p>
<p>[root@local~]# awk -v COLUMN=n &#8216;{sum+=$COLUMN} END {print sum} &#8217;file (s) </p>
<p>&nbsp; </p>
<p>5. 微调上述报告，产生字段n 的平均值: </p>
<p>[root@local~]# awk -v COLUMN=n &#8216;{sum+=$COLUMN} END {print sum/NR } &#8217;file (s) </p>
<p>6. 针对花费文件( 其记录包含描述与金额于最后一个字段) ，打印花费总数。可使用内建变量NF 计算总值: </p>
<p>[root@local~]# awk&#8217;{sum+=$NF; print $0, sum}&#8217;files) </p>
<p>&nbsp; </p>
<p>7. 这里是三种查找文件内文本的方式: </p>
<p>[root@local~]#egrep &#8216;pattern|pattern&#8217; file (s) </p>
<p>[root@local~]#awk &#8216;/pattern|pattern/&#8217;file (s) </p>
<p>[root@local~]#awk &#8216;/pattern}pattern/ {print FILENAME &#8221;: &#8221;FNR &#8221;: &#8221;$0} &#8217;file(s) </p>
<p>&nbsp;</p>
<p><br>8. 如果你要限制仅查找100 一150 行，可以通过两个工具程序，再搭配管道，不过这么做会漏掉位置信息: </p>
<p>[root@local~]#sed -n -e 100,150p -s file(s) | egrep 'pattern' </p>
<p>使用GNU sed 要搭配-s 选项，才能为每个文件重新开始行编号。另外，你也可以通过awk ，使用比较花哨的模式来做: </p>
<p>[root@local~]#awk &#8216;(100&lt;=FNR) &amp;&amp; (FNR &lt;= 150) &amp;&amp; /pattern/\ </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {print FILENAME &#8221;:&#8221; FNR &#8221;:&#8221;$0}&#8217;file(s) </p>
<p>9. 要在一个四栏表格里，调换第二与第三栏，假设它们是以制表字符分隔，那么可以 </p>
<p>使用下面三种方式的其中一种: </p>
<p>[root@local~]#awk -F'\t&#8217;-v OFS='\t&#8217;{print $1, $3, $2, $4}&#8217;old &gt; new </p>
<p>[root@local~]#awk &#8216;BEGIN{FS=OFS="\t"}{print $1, $3 ，$2 ，$4} &#8217;old&gt;new </p>
<p>[root@local~]#awk &#8211;F &#8216;\t&#8217;{print $1"\t" $3"\t" $2"\t" $4}&#8217;old&gt;new </p>
<p>&nbsp; </p>
<p>10. 要将各栏分隔字符由制表字符( 在此以&#183;显示) 转换成&amp; ，可在以下两种方式择一: </p>
<p>[root@local~]#sed -e 's/ &#183;/&amp;/g' file(s) </p>
<p>[root@local~]#awk &#8216;{BEGIN{FS="\t";OFS= &#8220;&amp; &#8221;}{$1=$1; print} &#8217;file(s) </p>
<p>&nbsp; </p>
<p>11. 下面这两个管道，都为删除已排序流里的重复行 </p>
<p>[root@local~]#sort file(s)|uniq </p>
<p>[root@local~]# sort file(s)|awk &#8216;Last!=$0 { print }{Last=$0}&#8217; </p>
<p>&nbsp; </p>
<p>12. 将回车字符/ 换行字符的行终结，一致转换为以换行字符作为行终结，可在下列方 </p>
<p>式中选择一种: </p>
<p>[root@local~]#sed &#8211;e &#8216;s/\r$//&#8217; file(s) </p>
<p>[root@local~]#sed &#8211;e &#8216;s/^M$//&#8217; file(s) </p>
<p>[root@local~]# mawk &#8216;BEGIN {RS=&#8220;\r\n"} {print}&#8217;file(s) </p>
<p>&nbsp; </p>
<p>13. 要将单空格的文本行，转换为双空格的行，可在下列方式选择一种 </p>
<p>[root@local~]#sed &#8211;e &#8216;/s/$/\n/ &#8217;file(s) </p>
<p>[root@local~]#awk &#8216;BEGTN{ ORS = "\n\n"){print}&#8217;file(s) </p>
<p>[root@local~]#awk &#8216;BEGIN{ ORS="\n\n" }1 &#8217; file(s) </p>
<p>[root@local~]#awk {print $0 &#8220;\n&#8221;} &#8217; file(s) </p>
<p>[root@local~]#awk &#8216;{print;print &#8221; &#8221;} &#8217; file(s) </p>
<p>13. 语句 </p>
<p>13.1. 条件语句 </p>
<p>if(expressionl) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stateme 刀t1 </p>
<p>else if(expression2) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statement2 </p>
<p>else if(expression3) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statement3 </p>
<p>else if(expressionk) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statementk </p>
<p>else </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statementk+l </p>
<p>13.2. 重复执行 </p>
<p>awk 提供了 4 种重复执行语句 ( 循环 ): </p>
<p>1. 循环在起始处使用结束测试 : </p>
<p>while(expression) </p>
<p>statement </p>
<p>2. 循环在结尾处使用结束测试 : </p>
<p>do </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statement </p>
<p>while (expression) </p>
<p>3. 循环执行可计数的次数 : </p>
<p>for(expr1;expr2; expr3) </p>
<p>statement </p>
<p>4. 循环处理关联数组里的元素 : </p>
<p>for(key in array) </p>
<p>statement </p>
<p>例如： </p>
<p>for （name in telephone) </p>
<p>print name&#8220;\t" telephone[name] </p>
<p>13.3 数组成员测试 </p>
<p>成员测试key in array 是一个表达式: 如果key 为array 的一个索引元素，则计算为1( 真) 。如果key 不是array 的一个索引元素，则!(key in array) 为1 。 </p>
<p>对于具有多下标(subscript) 的数组，在测试时，请使用圆括号，并以逗点分隔下标列表:(i ，j ，&#8230;，n)in array </p>
<p>成员测试不可能建立数组元素，然而引用元素时，如果元素不存在，便会建立它。因此你应该这么写: </p>
<p>if("Sally" in telephone) </p>
<p>print "Sally is in the directory" </p>
<p>而非: </p>
<p>if (telephone["Sally"]!= &#8221;&#8221;) </p>
<p>&nbsp;&nbsp;&nbsp; print "Sally is in the directory" </p>
<p>因为第二种形式会在她(Sally) 不存在时，将其加入到目录里，并拥有一个空电话号码。 </p>
<p>重点是: 你必须能够区分寻找索引(index) 与寻找特定值(value) 的差异。索引成员测试需要固定的时间，而值的查找时间是与数组里元素的个数成正比，这点我们在先前已通过break 语句内的for 循环解释过了。如果你需要时常用到这两种运算，那么构建反索引数组会比较实用: </p>
<p>for (name in telephone) </p>
<p>name_by_telephone[telephone[name]]=name </p>
<p>接下来，你就可以使用name_by_telephone ["555-0136"] 在一定时间内找到&#8221;Carol" 。当然，这里假定所有的值是唯一的: 如果这两人共享同一个电话，则name_by_telephone 数组只会记录最后一个名称。只要稍做修改就能解决这个问题: </p>
<p>for (name in telephone) </p>
<p>{ </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (telephone[name] in name_by_telephone) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name_by_telephone[telephone[name]]=\ </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name_by_telephone [telephone[name]) &#8220;\t&#8221;name </p>
<p>e1se </p>
<p>name_by_telephone[telephone[name]]=name </p>
<p>现在，name_by_telephone 即包含了以制表字符分隔的具有相同电话号码的人名列表。 </p>
<p>14. 用户控制输入 </p>
<p>awk 也可以通过的getline 语句做这件事。getline 会返回一个值，当输入被成功读取时，它的返回值为++I ，而返回值为0 时，则表示在文件结尾，而-1 则表示错误。它的用法很多，见表。 </p>
<p>语法&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明 </p>
<p>getline&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从当前输入文件中，读取下一条记录，存入$0 ，并更新NF, NR 与FNR </p>
<p>getline var&nbsp;&nbsp; 从当前输入文件中，读取下一条记录，存入var ，并更新NR 与FNR </p>
<p>getline&lt;file&nbsp;&nbsp; 从file 文件中，读取下一条记录，存入$0 ，并更新NF, NR 与FNR </p>
<p>getline var&lt;file 从file 文件中，读取下一条记录，存入var ，并更新NF, NR 与FNR </p>
<p>cmd|getline&nbsp;&nbsp;&nbsp; 从外部命令cmd 读取下一条记录，存入$0 ，并更新NF </p>
<p>cmd|getline var 从外部命令cmd 读取下一条记录，存入var </p>
<p>&nbsp;</p>
<p><br>命令管道在awk 里可以发挥强大的功能。管道可以在字符字符串中标明，也可以包含任 </p>
<p>意的Shell 命令。这里是与getline 搭配使用，如下: </p>
<p>"date" I getline now </p>
<p>close("date") </p>
<p>print "The current time is".now </p>
<p>&nbsp; </p>
<p>接下来说明的是: 如何在循环里使用命令管道: </p>
<p>command="head -n 15 /etc/hosts" </p>
<p>while((command I getline s)&gt;0) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print s </p>
<p>close(command) </p>
<p>&nbsp; </p>
<p>15. 执行外部程序 </p>
<p>这里是解决电话名录排序问题较短的程序方案，使用临时性文件与systemty ，而非awk 管道: </p>
<p>tmpfile= &#8220;/tmp/telephone.tmp^ </p>
<p>for (name in telephone&gt; </p>
<p>print name "\t" telephone[name]&gt;tmpfile </p>
<p>close(tmpfilej </p>
<p>system("sort &lt; tmpfile &#8220;) </p>
<p>临时性文件必须在调用system() 之前关闭，以确保任何缓冲区输出都正确地记录在文件内。 </p>
<p>对于被system() 执行的命令并不需要调用close() ，因为close() 仅针对以I/O 重定向运算符所打开的文件或管道，还有getline, print 或printf 。 </p>
<p>传递给system[f 的命令可包含数行 </p>
<p>system("cat &lt;&lt;EOFILE\nuno\ndos\ntres\nEOFILE" </p>
<p>它产生的输出和从嵌入文件复制到标准输出一样 </p>
<p>Un0 </p>
<p>das </p>
<p>tres </p>
<p>16. 用户自定义函数 </p>
<p>函数定义如下: </p>
<p>function name(argl, }rg2, &#8230;，argn </p>
<p>{ </p>
<p>statements </p>
<p>} </p>
<p>指定的参数在函数体中用来当作局部变量，它们会隐藏任何相同名称的全局性变量。函数也可用于程序它处，调用的形式为: </p>
<p>name(exprl, expr2, &#8230;，expn)&nbsp; 忽略任何的返回值 </p>
<p>result=name(exprl, expr2, &#8230;，exprn) 将返回值存储到result 中 </p>
<p>&nbsp; </p>
<p>在每个调用点上的表达式，都提供初始值给函数参数型变量。以圆括号框起来的参数，必须紧接于函数名称之后，中间没有任何空白。 </p>
<p>对标量参数所做的变动，调用者无从得知，不过对数组的变动就可看见了。换句话说，标量为传值(by vaule ) ，而数组则为传引用(by reference): 这对C 语言也是这样。 </p>
<p>函数体里的return expression 语句会终止主体的执行，并将expression 的值与控制权传给调用点。如果expression 省略，则返回值由实现期定义。我们测试过的所有系统，返回的不是数字零就是空字符串。 </p>
<p>17. 字符串函数 </p>
<p>17.1. 子字符串提取 </p>
<p>提取子字符串的函数:substr(string, start, 1en) ，会返回一份由string 的start 字符开始，共len 个字符长度的子字符串副本。字符的位置，从1 开始编号:substr("abcde", 2, 3) 将返回。bcd" 。 len 参数可省略，省略时，则默认为length(string)-start+1 ，选出字符串的剩余部分。 </p>
<p>17.2. 字符串大小写转换 </p>
<p>tolower(string) 会返回将所有字母改为同义的小写的string 副本，而toupper(string) 则返回被改为大写字母的string 副本。所以tolower("aBcDeF123") 返回&#8221;abcdef123",toupper("aBcDeF123") 返回"ABCDEF123" 。 </p>
<p>17.3. 字符串大小写转换 </p>
<p>index(string,&nbsp; find) 查找string 里是否有字符串find ，然后返回string 里find 字符串的起始位置，如果在string 里找不到find ，则返回0 。例如index("abcdef","de") 会返回4 。 </p>
<p>17.4. 字符串匹配 </p>
<p>match （string, regexp) 将string 与正则表达式regexp 匹配，如果匹配，则返回 </p>
<p>匹配string 的索引，不匹配，则返回0 。这种方式提供了比表达式(string~regexp) 还多的信息，后者只能得到计算值1 或0 。另外match ( ) 也具有一个有用的副作用: 它会将全局变量RSTART 设为在string 中要开始匹配的索引值，而将RLENGTH 设为要匹配的长度。而匹配子字符串则以substr(string, RSTART, RLENGTH) 表示。 </p>
<p>17.5. 字符串替换 </p>
<p>awk 在字符串替换功能上，提供两个函数:sub(regexp, replacement, target) 与gsub(regexp, replacement, target), sub() 将target 与正则表达式regexp 进行匹配，将最左边最长的匹配部分替换为字符串replacement 。gsub() 的运行则有点类似，不过它会替换所有匹配的字符串( 前置g 表示global 全局之意) 。 </p>
<p>17.6. 字符串替换 </p>
<p>awk 针对当前输人记录$0 自动提供了方便的分割为字1,&nbsp; $}, &#8230;、$NF ，也可以函数来做:split(string, array, regexp) 将string 切割为片段，并存储到array 里的连续元素。在数组里，片段放置在匹配正则表达式regexp 的子字符串之间。如果regexp 省略，则使用内建字段分隔字符FS 的当前默认值。函数会返回array 里的元素数量。 </p>
<p>17.7. 字符串重建 </p>
<p>join() 可确保参数数组不会被引用到，除非索引是在范围之内。否则，一个具有数组长度为0 的调用可能会建立arrayfl3 ，而修改了调用者的数组。插人的字段分隔字符为普通字符串，而非正则表达式，所以针对传递给split() 的一般正则表达式，join() 不会重建精确的原始字符串。 </p>
<p>17.8. 字符串格式化 </p>
<p>最后一个与字符串相关的函数是在用户控制下格式化数字与字符串:sprintf (format,expression1, expression2, &#8230;) ，它会返回已格式化的字符串作为其函数值。printf() 的运行方式也是这样，只不过它会在标准输出或重定向的文件上显示格式化后的字符串，而不是返回其函数值。较新的程序语言以更强大的格式化函数来取代格式控制字符串，但相对而言让代码变得很冗长。按照传统的文本处理应用来说，sprintf 与printf </p>
<p>18. 数值函数 </p>
<p>函数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明 </p>
<p>atan2(y, x)&nbsp;&nbsp; y 返回y/x 的反正切，值介于-pai 与+pai 之间。 </p>
<p>cos(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回x 的余弦值( 以弧度(radians) 计算) ，该值介于-1 与+1 之间 </p>
<p>exp(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回x 的指数，ex, </p>
<p>int(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回x 的整数部分，截去前置的0 </p>
<p>log(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回x 的自然对数。 </p>
<p>rand()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回平均分布的虚拟随机r,O&lt;=r&lt;l </p>
<p>sin(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回x 的正弦值( 以弧度(radians] 计算) ，该值介于-1 与+1 之间 </p>
<p>sqrt(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回x 的平方 </p>
<p>srand(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设置虚拟随机产生器的种子为x ，并返回正确的种子。如果省略x ，则使用当前时间( 以秒计) 。如果。rand ( ) 未被调用，则awk 在每次执行时会从相同的默认种子开始;mawk 则不会。 </p>
<p><br>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/wzhwho/archive/2010/04/21/5513791.aspx">http://blog.csdn.net/wzhwho/archive/2010/04/21/5513791.aspx</a></p>
<img src ="http://www.cppblog.com/prayer/aggbug/124778.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-08-26 10:26 <a href="http://www.cppblog.com/prayer/archive/2010/08/26/124778.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>awk中使用的shell命令</title><link>http://www.cppblog.com/prayer/archive/2010/08/25/124714.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 25 Aug 2010 10:53:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/08/25/124714.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/124714.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/08/25/124714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/124714.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/124714.html</trackback:ping><description><![CDATA[<p>awk中使用的shell命令，有2种方法：<br><br><strong>一。使用所以system（）</strong></p>
<p>awk 'BEGIN {system("echo \"Input your name:\\c\""); getline d;print "\nYour name is",d,"\b!\n"}'</p>
<p>用（""）和\"&nbsp;&nbsp; \"&nbsp;&nbsp; \\转义。</p>
<p>&#160;</p>
<p>system - execute a shell command （）里面接入命令</p>
<p>awk程序中我们可以使用system() 函数去调用shell命令<br>如：awk 'BEGIN{system("echo abc")}' file<br>echo abc 就会做为&#8220;命令行&#8221;，由shell来执行，所以我们会得到以下结果：<br><br><br>root@ubuntu:~# awk 'BEGIN{system("echo abc")}'<br>abc<br>root@ubuntu:~#<br><br><br>root@ubuntu:~# awk 'BEGIN{v1="echo";v2="abc";system(v1" "v2)}'<br>abc<br>root@ubuntu:~#<br><br><br>root@ubuntu:~# awk 'BEGIN{v1="echo";v2="abc";system(v1 v2)}'<br>/bin/sh: echoabc: command not found<br>root@ubuntu:~#<br><br><br>root@ubuntu:~# awk 'BEGIN{v1=echo;v2=abc;system(v1" "v2)}'<br>root@ubuntu:~#<br><br>从上面的例子，我们简单的分析一下awk是怎样调用system的：<br>如果system（）括号里面的参数没有加上双引号的话，awk认为它是一个变量，它会从awk的变量里面把它们先置换为常量，然后再回传给shell<br><br>如果system（）括号里面的参数有加上双引号的话，那么awk就直接把引号里面的内容回传给shell，作为shell的&#8220;命令行&#8221;<br><br><strong>二。使用print cmd | &#8220;/bin/bash&#8221;</strong><br><br>root@ubuntu:~# awk 'BEGIN{print "echo","abc"| "/bin/bash"}'<br>abc<br>root@ubuntu:~#<br><br>root@ubuntu:~# awk 'BEGIN{print "echo","abc",";","echo","123"| "/bin/bash"}'<br>abc<br>123<br>root@ubuntu:~#<br><br><br><strong>三。总结</strong><br><br>无论使用system（）还是print cmd | &#8220;/bin/bash&#8221;<br>awk都是新开一个shell，在相应的cmdline参数送回给shell，所以要注意当前shell变量与新开shell变量问题<br><br>1.1<br>root@ubuntu:~# abc=12345567890<br>root@ubuntu:~# awk 'BEGIN{system("echo $abc")}'<br><br>root@ubuntu:~#<br><br><br>1.2<br>root@ubuntu:~# export abc=12345567890<br>root@ubuntu:~# awk 'BEGIN{system("echo $abc")}'<br>12345567890<br>root@ubuntu:~#<br><br>2.1<br>root@ubuntu:~# abc=1234567890<br>root@ubuntu:~# awk 'BEGIN{print "echo","$abc"| "/bin/bash"}'<br><br>root@ubuntu:~#<br><br><br>2.2<br>root@ubuntu:~# export abc=1234567890<br>root@ubuntu:~# awk 'BEGIN{print "echo","$abc"| "/bin/bash"}'<br>1234567890<br>root@ubuntu:~#<br><br><br>以上例子，没有export的话，那些变量都是只存在于当前shell变量中，所以都是echo不出来的 ，<br>而使用了 export的都是环境变量，所以awk调用新的shell时候，可以echo出来</p>
<img src ="http://www.cppblog.com/prayer/aggbug/124714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-08-25 18:53 <a href="http://www.cppblog.com/prayer/archive/2010/08/25/124714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux Shell真是无所不能之split命令。</title><link>http://www.cppblog.com/prayer/archive/2010/08/25/124637.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 25 Aug 2010 03:08:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/08/25/124637.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/124637.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/08/25/124637.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/124637.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/124637.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 突然发现到Linux shell命令的强大，有时在Windows需要一个软件的操作，在ubuntu终端执行一条命令就可以。
<p>比如：</p>
<p>split命令</p>
<p>语法:komy@komy-vmware:~$ <font color=#ff0000><strong>split [-bl] 输入文件 输出文件</strong></font></p>
<p><font color=#000000>参数说明</font></p>
<p><font color=#000000>-b :以文件大小来分</font></p>
<p><font color=#000000>-l：以行数来分</font></p>
<p><font color=#000000>例如split -l 100 test.txt out</font></p>
<p><font color=#000000>就是把test.txt每100行输出一个文件outaa,outab,outcd以此类推。。。实现了文本文件的分割。</font></p>
<p><font color=#000000>split -b 100k test.txt out</font></p>
<p><font color=#000000>就是把test.txt每100KB输出一个文件outaa,outab,outcd以此类推。</font></p>
<p><font color=#000000>这两个命令对于手机看小说有限制的情况下很受用。。。</font></p>
<p><font color=#000000>不仅仅如此cat 命令可将这些分割后的文件合并为一个文件，并重定向到&#8220;largefile&#8221;文件中（largefile为自定的文件名）。 </font></p>
<p style="TEXT-INDENT: 2em"></p>
<p style="TEXT-INDENT: 2em">komy@komy-vmware:~$ <font color=#ff0000><strong>cat out* &gt; largeflie</strong></font></p>
<img src ="http://www.cppblog.com/prayer/aggbug/124637.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-08-25 11:08 <a href="http://www.cppblog.com/prayer/archive/2010/08/25/124637.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell读取行经典代码（ZZ）</title><link>http://www.cppblog.com/prayer/archive/2010/08/14/123455.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Sat, 14 Aug 2010 11:44:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/08/14/123455.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/123455.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/08/14/123455.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/123455.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/123455.html</trackback:ping><description><![CDATA[#!/usr/bin/ksh<br>#<br># SCRIPT: 12_ways_to_parse.ksh.ksh<br>#<br>#<br># REV: 1.2.A<br>#<br># PURPOSE:&nbsp;&nbsp; This script shows the different ways of reading<br># &nbsp;&nbsp; a file line by line.&nbsp;&nbsp; Again there is not just one way<br># &nbsp;&nbsp; to read a file line by line and some are faster than<br># &nbsp;&nbsp; others and some are more intuitive than others.<br>#<br># REV LIST:<br>#<br># &nbsp;&nbsp; 03/15/2002 - Randy Michael<br># &nbsp;&nbsp; Set each of the while loops up as functions and the timing<br># &nbsp;&nbsp; of each function to see which one is the fastest.<br>#<br>#######################################################################<br>#<br># &nbsp;&nbsp; NOTE: To output the timing to a file use the following syntax:<br>#<br># &nbsp;&nbsp; &nbsp;&nbsp; 12_ways_to_parse.ksh file_to_process&nbsp;&nbsp; &gt; output_file_name 2&gt;&amp;1<br>#<br># &nbsp;&nbsp; The actaul timing data is sent to standard error, file <br># &nbsp;&nbsp; descriptor (2), and the function name header is sent<br># &nbsp;&nbsp; to standard output, file descriptor (1).<br>#<br>#######################################################################<br>#<br># set -n&nbsp;&nbsp; # Uncomment to check command syntax without any execution<br># set -x&nbsp;&nbsp; # Uncomment to debug this script<br>#<br><br>FILENAME="$1"<br>TIMEFILE="/tmp/loopfile.out"<br>&gt;$TIMEFILE<br>THIS_SCRIPT=$(basename $0)<br><br>######################################<br>function usage<br>{<br>echo "\nUSAGE: $THIS_SCRIPT&nbsp;&nbsp; file_to_process\n"<br>echo "OR - To send the output to a file use: "<br>echo "\n$THIS_SCRIPT&nbsp;&nbsp; file_to_process&nbsp;&nbsp; &gt; output_file_name 2&gt;&amp;1 \n"<br>exit 1<br>}<br>######################################<br>function while_read_LINE<br>{<br>cat $FILENAME | while read LINE<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done<br>}<br>######################################<br>function while_read_LINE_bottom <br>{<br>while read LINE<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br><br>done &lt; $FILENAME<br>}<br>######################################<br>function while_line_LINE_bottom<br>{<br>while line LINE<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo $LINE<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done &lt; $FILENAME<br>}<br>######################################<br>function cat_while_LINE_line&nbsp;&nbsp;<br>{<br>cat $FILENAME | while LINE=`line`<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done<br>}<br>######################################<br>function while_line_LINE<br>{<br>cat $FILENAME | while line LINE<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done<br>}<br>######################################<br>function while_LINE_line_bottom <br>{<br>while LINE=`line`<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br><br>done &lt; $FILENAME <br>}<br>######################################<br>function while_LINE_line_cmdsub2 <br>{<br>cat $FILENAME | while LINE=$(line)<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done<br>}<br>######################################<br>function while_LINE_line_bottom_cmdsub2 <br>{<br>while LINE=$(line)<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br><br>done &lt; $FILENAME <br>}<br>######################################<br>function while_read_LINE_FD <br>{<br>exec 3&lt;&amp;0<br>exec 0&lt; $FILENAME<br>while read LINE<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done<br>exec 0&lt;&amp;3<br>}<br>######################################<br>function while_LINE_line_FD <br>{<br>exec 3&lt;&amp;0<br>exec 0&lt; $FILENAME<br>while LINE=`line`<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done<br>exec 0&lt;&amp;3<br>}<br>######################################<br>function while_LINE_line_cmdsub2_FD<br>{<br>exec 3&lt;&amp;0<br>exec 0&lt; $FILENAME<br>while LINE=$(line)<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; print "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done<br>exec 0&lt;&amp;3<br>}<br>######################################<br>function while_line_LINE_FD <br>{<br>exec 3&lt;&amp;0<br>exec 0&lt; $FILENAME<br><br>while line LINE<br>do<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; echo "$LINE"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; :<br>done<br><br>exec 0&lt;&amp;3<br>}<br>######################################<br>########### START OF MAIN ############<br>######################################<br><br># Test the Input<br><br># Looking for exactly one parameter<br>(( $# == 1 )) || usage<br><br># Does the file exist as a regular file?<br>[[ -f $1 ]] || usage<br><br>echo "\nStarting File Processing of each Method\n"<br><br>echo "Method 1:"<br>echo "\nfunction while_read_LINE\n" &gt;&gt; $TIMEFILE<br>echo "function while_read_LINE"<br>time while_read_LINE &gt;&gt; $TIMEFILE<br>echo "\nMethod 2:"<br>echo "\nfunction while_read_LINE_bottom\n" &gt;&gt; $TIMEFILE<br>echo "function while_read_LINE_bottom"<br>time while_read_LINE_bottom &gt;&gt; $TIMEFILE<br>echo "\nMethod 3:"<br>echo "\nfunction while_line_LINE_bottom\n" &gt;&gt; $TIMEFILE<br>echo "function while_line_LINE_bottom"<br>time while_line_LINE_bottom &gt;&gt; $TIMEFILE<br>echo "\nMethod 4:"<br>echo "\nfunction cat_while_LINE_line\n" &gt;&gt; $TIMEFILE<br>echo "function cat_while_LINE_line"<br>time cat_while_LINE_line &gt;&gt; $TIMEFILE<br>echo "\nMethod 5:"<br>echo "\nfunction while_line_LINE\n" &gt;&gt; $TIMEFILE<br>echo "function while_line_LINE"<br>time while_line_LINE &gt;&gt; $TIMEFILE<br>echo "\nMethod 6:"<br>echo "\nfunction while_LINE_line_bottom\n" &gt;&gt; $TIMEFILE<br>echo "function while_LINE_line_bottom"<br>time while_LINE_line_bottom &gt;&gt; $TIMEFILE<br>echo "\nMethod 7:"<br>echo "\nfunction while_LINE_line_cmdsub2\n" &gt;&gt; $TIMEFILE<br>echo "function while_LINE_line_cmdsub2"<br>time while_LINE_line_cmdsub2 &gt;&gt; $TIMEFILE<br>echo "\nMethod 8:"<br>echo "\nfunction while_LINE_line_bottom_cmdsub2\n" &gt;&gt; $TIMEFILE<br>echo "function while_LINE_line_bottom_cmdsub2"<br>time while_LINE_line_bottom_cmdsub2 &gt;&gt; $TIMEFILE<br>echo "\nMethod 9:"<br>echo "\nfunction while_read_LINE_FD\n" &gt;&gt; $TIMEFILE<br>echo "function while_read_LINE_FD"<br>time while_read_LINE_FD &gt;&gt; $TIMEFILE<br>echo "\nMethod 10:"<br>echo "\nfunction while_LINE_line_FD\n" &gt;&gt; $TIMEFILE<br>echo "function while_LINE_line_FD"<br>time while_LINE_line_FD &gt;&gt; $TIMEFILE<br>echo "\nMethod 11:"<br>echo "\nfunction while_LINE_line_cmdsub2_FD\n" &gt;&gt; $TIMEFILE<br>echo "function while_LINE_line_cmdsub2_FD"<br>time while_LINE_line_cmdsub2_FD &gt;&gt; $TIMEFILE<br>echo "\nMethod 12:"<br>echo "\nfunction while_line_LINE_FD\n" &gt;&gt; $TIMEFILE<br>echo "function while_line_LINE_FD"<br>time while_line_LINE_FD &gt;&gt; $TIMEFILE
<img src ="http://www.cppblog.com/prayer/aggbug/123455.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-08-14 19:44 <a href="http://www.cppblog.com/prayer/archive/2010/08/14/123455.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell的效率不如perl或Python? </title><link>http://www.cppblog.com/prayer/archive/2010/06/07/117311.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 07 Jun 2010 04:25:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/06/07/117311.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/117311.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/06/07/117311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/117311.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/117311.html</trackback:ping><description><![CDATA[<div class="postmessage ">
<div class=t_msgfontfix>
<table cellSpacing=0 cellPadding=0>
    <tbody>
        <tr>
            <td class=t_msgfont id=postmessage_12261486>shell文本处理方面，主要是有sed，awk这两把刀。<br><br>光给你个shell你进行文本处理是做不到的，当然简单的还可以。<br><br>perl里有正则表达式引擎，能针对文本进行拆分替换等复杂操作，关键是，perl不用fork出新的进程来处理这些事情，而shell需要使用管道等通过这些sed，awk的进程来处理，至少就多出部分进程的开销。<br><br>而且，管道这个东西，原本一个工具一次能完成的任务，在需要经过sed，和awk等多次管道。效率可想而知。<br><br>其实你这个问题问的有点弱智，SHELL是什么？<br><br>SHELL只是一个接口，大部分的功能全靠外部程序来完成。<br>而Perl是一种语言，基本上什么事情都能做。</td>
        </tr>
    </tbody>
</table>
</div>
</div>
<br><br>老老实实学好一样东西最实际。<br>当你参加面试的时候，如果可以自信的说自己熟练使用Shell或者Perl，那就相当不错了。<br>效率之类的云云，具体问题具体分析吧，能解决工作中遇到的问题就行。<br><br><br>
<div class="postmessage ">
<div class=t_msgfontfix>
<table cellSpacing=0 cellPadding=0>
    <tbody>
        <tr>
            <td class=t_msgfont id=postmessage_12262758>看出来楼主比较关心文本处理，下面这个比方不一定恰当，但已经很接近了：<br><br>
            <ul><br>
                <li>相比较而言，awk、sed就像死板手，而perl和python是个活板手。<br>
                <li>awk和sed专注于文本处理，大部分情况效率要优于perl等。很简单，比如列文件，谁能有cat的效率高？<br>
                <li>如果你是个懒惰的SA，那就用shell吧。如果是geek或者你的工作需要复杂的逻辑，并且还会出现许多无法预知的新要求，那就用perl等好了。<br></li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div id=post_rate_div_12262758></div>
</div>
<br><br>没那么多关键字，是打字手误，但是1-10万数量级的关键字，在千万行级文本文件中搜索，这个量还是有的。<br><br>来段sed multiple keywords search in batch的代码，欢迎其他新想法。
<div class=blockcode>
<div id=code0>
<ol>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local num_in_batch=300<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local batch_counter=0<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local log_display_in_batch=1000<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local bbl_counter=0<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local num_in_bl_counter=0<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; declare -a bbl_arr=()<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local keyword=<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local keyword_del<br>
    <li><br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logMsg $debug_flag null "Starting blacklist checking in batch."<br>
    <li><br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for msisdn in `cut -d: -f2 $tmpfile`; do&nbsp; &nbsp; &nbsp; &nbsp; <br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ $batch_counter -eq $num_in_batch ]; then<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keyword="${keyword}$msisdn"<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bbl_arr=(`sed -rn "/$keyword/p" $filter_file`)<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local num=${#bbl_arr[@]}<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((num_in_bl_counter+=num))<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ $num -gt 1 ]; then<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keyword_del=`echo ${bbl_arr[@]} | tr " " "|"`<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sed -ri "/${keyword_del}/d" $inputfile<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keyword=<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; batch_counter=0<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keyword="${keyword}$msisdn|"<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if [ $((bbl_counter%log_display_in_batch)) -eq 0 ]; then<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logMsg $debug_flag null "$bbl_counter MSISDN processed."<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fi<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((batch_counter++))<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((bbl_counter++))<br>
    <li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; done</li>
</ol>
</div>
<em onclick="copycode($('code0'));">复制代码</em></div>
<img src ="http://www.cppblog.com/prayer/aggbug/117311.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-06-07 12:25 <a href="http://www.cppblog.com/prayer/archive/2010/06/07/117311.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sort -T</title><link>http://www.cppblog.com/prayer/archive/2010/05/12/115191.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 12 May 2010 06:14:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/05/12/115191.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/115191.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/05/12/115191.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/115191.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/115191.html</trackback:ping><description><![CDATA[&nbsp;-T Directory<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Places all temporary files that are created into the directory specified by the Directory parameter.
<img src ="http://www.cppblog.com/prayer/aggbug/115191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-05-12 14:14 <a href="http://www.cppblog.com/prayer/archive/2010/05/12/115191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sort 指定排序域的两种方法</title><link>http://www.cppblog.com/prayer/archive/2010/05/12/115190.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 12 May 2010 06:12:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/05/12/115190.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/115190.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/05/12/115190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/115190.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/115190.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The -k KeyDefinition flag uses the following form:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -k [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The sort key includes all characters beginning with the field specified by the FStart variable and the column specified by<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the CStart variable and ending with the field specified by the FEnd variable and the column specified by the CEnd variable.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If Fend is not specified, the last character of the line is assumed. If CEnd is not specified the last character in the<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FEnd field is assumed. Any field or column number in the KeyDefinition variable may be omitted. The default values are:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FStart<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Beginning of the line<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CStart<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; First column in the field</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FEnd<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End of the line<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CEnd<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Last column of the field</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If there is any spaces between the fields, sort considers them as separate fields.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The value of the Modifier variable can be one or more of the letters b, d, f, i, n, or r. The modifiers apply only to the<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; field definition they are attached to and have the same effect as the flag of the same letter. The modifier letter b<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; applies only to the end of the field definition to which it is attached. For example:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -k 3.2b,3r</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; specifies a sort key beginning in the second nonblank column of the third field and extending to the end of the third<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; field, with the sort on this key to be done in reverse collation order. If the FStart variable and the CStart variable fall<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; beyond the end of the line or after the FEnd variable and the CEnd variable, then the sort key is ignored.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A sort key can also be specified in the following manner:</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [+[FSkip1] [.CSkip1] [Modifier] ] [-[FSkip2] [.CSkip2] [Modifier]]</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The +FSkip1 variable specifies the number of fields skipped to reach the first field of the sort key and the +CSkip<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variable specifies the number of columns skipped within that field to reach the first character in the sort key. The -FSkip<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variable specifies the number of fields skipped to reach the first character after the sort key, and the -CSkip variable<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; specifies the number of columns to skip within that field. Any of the field and column skip counts may be omitted. The<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defaults are:</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FSkip1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Beginning of the line<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CSkip1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Zero<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FSkip2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End of the line<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CSkip2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Zero</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The modifiers specified by the Modifier variable are the same as in the -k flag key sort definition.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The field and column numbers specified by +FSkip1.CSkip1 variables are generally one less than the field and column number<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; of the sort key itself because these variables specify how many fields and columns to skip before reaching the sort key.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For example:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +2.1b -3r</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; specifies a sort key beginning in the second nonblank column of the third field and extending to the end of the third<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; field, with the sort on this key to be done in reverse collation order. The statement +2.1b specifies that two fields are<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; skipped and then the leading blanks and one more column are skipped. If the +FSkip1.CSkip1 variables fall beyond the end of</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the line or after the -FSkip2.CSkip2 variables, then the sort key is ignored.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Note: The maximum number of fields on a line is 10.</p>
<img src ="http://www.cppblog.com/prayer/aggbug/115190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-05-12 14:12 <a href="http://www.cppblog.com/prayer/archive/2010/05/12/115190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《sort命令的k选项大讨论》-linux命令五分钟系列之二十七</title><link>http://www.cppblog.com/prayer/archive/2010/05/12/115187.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 12 May 2010 05:34:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/05/12/115187.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/115187.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/05/12/115187.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/115187.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/115187.html</trackback:ping><description><![CDATA[<p><strong>本原创文章属于<a href="http://roclinux.cn/" target=_blank><u><font color=#e08105>《Linux大棚》</font></u></a>博客，博客地址为<a href="http://roclinux.cn/" target=_blank><u><font color=#e08105>http://roclinux.cn</font></u></a>。文章作者为rocrocket。</strong></p>
<p><span style="COLOR: #000000"></span><span style="COLOR: #000000"><strong>为了防止某些网站的恶性转载，特在每篇文章前加入此信息，还望读者体谅。</strong></span></p>
<p><strong>===</strong></p>
<p><span style="COLOR: #993300"><strong>[正文开始]</strong></span><br>有时候学习脚本，你会发现sort命令后面跟了一堆类似-k1,2，或者-k1.2 -k3.4的东东，有些匪夷所思。今天，我们就来搞定它—-k选项！</p>
<p><strong>1 准备素材</strong></p>
<p>$ cat facebook.txt<br>google 110 5000<br>baidu 100 5000<br>guge 50 3000<br>sohu 100 4500</p>
<p><span id=more-1472></span></p>
<p>第一个域是公司名称，第二个域是公司人数，第三个域是员工平均工资。（除了公司名称，其他的别信，都瞎写的^_^）</p>
<p><strong>2 我想让这个文件按公司的字母顺序排序，也就是按第一个域进行排序：（这个facebook.txt文件有三个域）</strong></p>
<p>$ sort -t &#8216; &#8216; -k 1 facebook.txt<br>baidu 100 5000<br>google 110 5000<br>guge 50 3000<br>sohu 100 4500</p>
<p>看到了吧，就直接用-k 1设定就可以了。（其实此处并不严格，稍后你就会知道）</p>
<p><strong>3 我想让facebook.txt按照公司人数排序</strong></p>
<p>$ sort -n -t &#8216; &#8216; -k 2 facebook.txt<br>guge 50 3000<br>baidu 100 5000<br>sohu 100 4500<br>google 110 5000</p>
<p>不用解释，我相信你能懂。</p>
<p>但是，此处出现了问题，那就是baidu和sohu的公司人数相同，都是100人，这个时候怎么办呢？按照默认规矩，是从第一个域开始进行升序排序，因此baidu排在了sohu前面。</p>
<p><strong>4&nbsp; 我想让facebook.txt按照公司人数排序 ，人数相同的按照员工平均工资升序排序：</strong></p>
<p>$ sort -n -t &#8216; &#8216; -k 2 -k 3 facebook.txt<br>guge 50 3000<br>sohu 100 4500<br>baidu 100 5000<br>google 110 5000</p>
<p>看，我们加了一个-k2 -k3就解决了问题。对滴，sort支持这种设定，就是说设定域排序的优先级，先以第2个域进行排序，如果相同，再以第3个域进行排序。（如果你愿意，可以一直这么写下去，设定很多个排序优先级）</p>
<p><strong>5 我想让facebook.txt按照员工工资降序排序，如果员工人数相同的，则按照公司人数升序排序：（这个有点难度喽）</strong></p>
<p>$ sort -n -t &#8216; &#8216; -k 3r -k 2 facebook.txt<br>baidu 100 5000<br>google 110 5000<br>sohu 100 4500<br>guge 50 3000</p>
<p>此处有使用了一些小技巧，你仔细看看，在-k 3后面偷偷加上了一个小写字母r。你想想，再结合我们<a href="http://roclinux.cn/?p=1350" target=_blank><u><font color=#e08105>上一篇文章</font></u></a>，能得到答案么？揭晓：r和-r选项的作用是一样的，就是表示逆序。因为sort默认是按照升序排序的，所以此处需要加上r表示第三个域（员工平均工资）是按照降序排序。此处你还可以加上n，就表示对这个域进行排序时，要按照数值大小进行排序，举个例子吧：</p>
<p>$ sort -t &#8216; &#8216; -k 3nr -k 2n facebook.txt<br>baidu 100 5000<br>google 110 5000<br>sohu 100 4500<br>guge 50 3000</p>
<p>看，我们去掉了最前面的-n选项，而是将它加入到了每一个-k选项中了。</p>
<p><strong>6 -k选项的具体语法格式</strong></p>
<p>要继续往下深入的话，就不得不来点理论知识。你需要了解-k选项的语法格式，如下：</p>
<p>[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]</p>
<p>这个语法格式可以被其中的逗号（&#8220;，&#8221;）分为两大部分，Start部分和End部分。</p>
<p>先给你灌输一个思想，那就是&#8220;如果不设定End部分，那么就认为End被设定为行尾&#8221;。这个概念很重要的，但往往你不会重视它。</p>
<p>Start部分也由三部分组成，其中的Modifier部分就是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStart和C.Start。</p>
<p>C.Start也是可以省略的，省略的话就表示从本域的开头部分开始。之前例子中的-k 2和-k 3就是省略了C.Start的例子喽。</p>
<p>FStart.CStart，其中FStart就是表示使用的域，而CStart则表示在FStart域中从第几个字符开始算&#8220;排序首字符&#8221;。</p>
<p>同理，在End部分中，你可以设定FEnd.CEnd，如果你省略.CEnd，则表示结尾到&#8220;域尾&#8221;，即本域的最后一个字符。或者，如果你将CEnd设定为0(零)，也是表示结尾到&#8220;域尾&#8221;。</p>
<p><strong>7 突发奇想，从公司英文名称的第二个字母开始进行排序：</strong></p>
<p>$ sort -t &#8216; &#8216; -k 1.2 facebook.txt<br>baidu 100 5000<br>sohu 100 4500<br>google 110 5000<br>guge 50 3000</p>
<p>看，我们使用了-k 1.2，这就表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。你会发现baidu因为第二个字母是a而名列榜首。sohu和google第二个字符都是o，但sohu的h在google的o前面，所以两者分别排在第二和第三。guge只能屈居第四了。</p>
<p><strong>8 又突发奇想，，只针对公司英文名称的第二个字母进行排序，如果相同的按照员工工资进行降序排序：</strong></p>
<p>$ sort -t &#8216; &#8216; -k 1.2,1.2 -k 3,3nr facebook.txt<br>baidu 100 5000<br>google 110 5000<br>sohu 100 4500<br>guge 50 3000</p>
<p>由于只对第二个字母进行排序，所以我们使用了-k 1.2,1.2的表示方式，表示我们&#8220;只&#8221;对第二个字母进行排序。（如果你问&#8220;我使用-k 1.2怎么不行？&#8221;，当然不行，因为你省略了End部分，这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序）。对于员工工资进行排序，我们也使用了-k 3,3，这是最准确的表述，表示我们&#8220;只&#8221;对本域进行排序，因为如果你省略了后面的3，就变成了我们&#8220;对第3个域开始到最后一个域位置的内容进行排序&#8221;了。</p>
<p><strong>9 在modifier部分还可以用到哪些选项？</strong></p>
<p>可以用到b、d、f、i、n 或 r。</p>
<p>其中n和r你肯定已经很熟悉了。</p>
<p>b表示忽略本域的签到空白符号。</p>
<p>d表示对本域按照字典顺序排序（即，只考虑空白和字母）。</p>
<p>f表示对本域忽略大小写进行排序。</p>
<p>i表示忽略&#8220;不可打印字符&#8221;，只针对可打印字符进行排序。（有些ASCII就是不可打印字符，比如\a是报警，\b是退格，\n是换行，\r是回车等等）</p>
<p><strong>10 思考思考关于-k和-u联合使用的例子：</strong></p>
<p>$ cat facebook.txt<br>google 110 5000<br>baidu 100 5000<br>guge 50 3000<br>sohu 100 4500</p>
<p>这是最原始的facebook.txt文件。</p>
<p>$ sort -n -k 2 facebook.txt<br>guge 50 3000<br>baidu 100 5000<br>sohu 100 4500<br>google 110 5000</p>
<p>$ sort -n -k 2 -u facebook.txt<br>guge 50 3000<br>baidu 100 5000<br>google 110 5000</p>
<p>当设定以公司员工域进行数值排序，然后加-u后，sohu一行就被删除了！原来-u只识别用-k设定的域，发现相同，就将后续相同的行都删除。</p>
<p>$ sort&nbsp; -k 1 -u facebook.txt<br>baidu 100 5000<br>google 110 5000<br>guge 50 3000<br>sohu 100 4500</p>
<p>$ sort&nbsp; -k 1.1,1.1 -u facebook.txt<br>baidu 100 5000<br>google 110 5000<br>sohu 100 4500</p>
<p>这个例子也同理，开头字符是g的guge就没有幸免于难。</p>
<p>$ sort -n -k 2 -k 3 -u facebook.txt<br>guge 50 3000<br>sohu 100 4500<br>baidu 100 5000<br>google 110 5000</p>
<p>咦！这里设置了两层排序优先级的情况下，使用-u就没有删除任何行。原来-u是会权衡所有-k选项，将都相同的才会删除，只要其中有一级不同都不会轻易删除的:)（不信，你可以自己加一行sina 100 4500试试看）</p>
<p><strong>11 最诡异的排序：</strong></p>
<p>$ sort -n -k 2.2,3.1 facebook.txt<br>guge 50 3000<br>baidu 100 5000<br>sohu 100 4500<br>google 110 5000</p>
<p>以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。</p>
<p>第一行，会提取0 3，第二行提取00 5，第三行提取00 4，第四行提取10 5。</p>
<p>又因为sort认为0小于00小于000小于0000&#8230;.</p>
<p>因此0 3肯定是在第一个。10 5肯定是在最后一个。但为什么00 5却在00 4前面呢？（你可以自己做实验思考一下。）</p>
<p>答案揭晓：原来&#8220;跨域的设定是个假象&#8221;，sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分，而不会把第三个域的开头字符纳入比较范围。当发现00和00相同时，sort就会自动比较第一个域去了。当然baidu在sohu前面了。用一个范例即可证实：</p>
<p>$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt<br>guge 50 3000<br>sohu 100 4500<br>baidu 100 5000<br>google 110 5000</p>
<p><strong>12 有时候在sort命令后会看到+1 -2这些符号，这是什么东东？</strong></p>
<p>关于这种语法，最新的sort是这么进行解释的：</p>
<p>On older systems, `sort&#8217; supports an obsolete origin-zero syntax `+POS1 [-POS2]&#8216; for specifying sort keys.&nbsp; POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use `-k&#8217; instead.</p>
<p>原来，这种古老的表示方式已经被淘汰了，以后可以理直气壮的鄙视使用这种表示方法的脚本喽！</p>
<p>（为了防止古老脚本的存在，在这再说一下这种表示方法，加号表示Start部分，减号表示End部分。最最重要的一点是，这种方式方法是从0开始计数的，以前所说的第一个域，在此被表示为第0个域。以前的第2个字符，在此表示为第1个字符。明白？）</p>
<p><span style="COLOR: #0000ff"><strong>结束语：</strong></span></p>
<p><span style="COLOR: #0000ff"><strong>本文是互联网上仅有的比较全的关于sort的k选项的论述文章，如需转载请务必注明&#8220;转自Linux大棚-Linux主题博客&#8221;，谢谢各位:)</strong></span></p>
<p><span style="COLOR: #0000ff"><strong>sort的-k选项基本就是这堆内容了，如果大家有什么补充，就留言吧:) 欢迎交流！</strong></span></p>
<img src ="http://www.cppblog.com/prayer/aggbug/115187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-05-12 13:34 <a href="http://www.cppblog.com/prayer/archive/2010/05/12/115187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《sort帮你排序》-linux命令五分钟系列之二十六 -o选项</title><link>http://www.cppblog.com/prayer/archive/2010/05/12/115186.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 12 May 2010 05:32:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/05/12/115186.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/115186.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/05/12/115186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/115186.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/115186.html</trackback:ping><description><![CDATA[<p>sort是在Linux里非常常用的一个命令，管排序的，集中精力，五分钟搞定sort，现在开始！</p>
<p><strong>1 sort的工作原理</strong></p>
<p><span id=more-1350></span></p>
<p>sort将文件的每一行作为一个单位，相互比较，比较原则是从首字符向后，依次按ASCII码值进行比较，最后将他们按升序输出。</p>
<p>[rocrocket@rocrocket programming]$ cat seq.txt<br>banana<br>apple<br>pear<br>orange<br>[rocrocket@rocrocket programming]$ sort seq.txt<br>apple<br>banana<br>orange<br>pear</p>
<p><strong>2 sort的-u选项</strong></p>
<p>它的作用很简单，就是在输出行中去除重复行。</p>
<p>[rocrocket@rocrocket programming]$ cat seq.txt<br>banana<br>apple<br>pear<br>orange<br>pear<br>[rocrocket@rocrocket programming]$ sort seq.txt<br>apple<br>banana<br>orange<br>pear<br>pear<br>[rocrocket@rocrocket programming]$ sort -u seq.txt<br>apple<br>banana<br>orange<br>pear</p>
<p>pear由于重复被-u选项无情的删除了。</p>
<p><strong>3 sort的-r选项</strong></p>
<p>sort默认的排序方式是升序，如果想改成降序，就加个-r就搞定了。</p>
<p>[rocrocket@rocrocket programming]$ cat number.txt<br>1<br>3<br>5<br>2<br>4<br>[rocrocket@rocrocket programming]$ sort number.txt<br>1<br>2<br>3<br>4<br>5<br>[rocrocket@rocrocket programming]$ sort -r number.txt<br>5<br>4<br>3<br>2<br>1</p>
<p><strong>4 sort的-o选项</strong></p>
<p>由于sort默认是把结果输出到标准输出，所以需要用重定向才能将结果写入文件，形如sort filename &gt; newfile。</p>
<p>但是，如果你想把排序结果输出到原文件中，用重定向可就不行了。</p>
<p>[rocrocket@rocrocket programming]$ sort -r number.txt &gt; number.txt<br>[rocrocket@rocrocket programming]$ cat number.txt<br>[rocrocket@rocrocket programming]$<br>看，竟然将number清空了。</p>
<p><strong>就在这个时候，-o选项出现了，它成功的解决了这个问题，让你放心的将结果写入原文件。这或许也是-o比重定向的唯一优势所在。</strong></p>
<p>[rocrocket@rocrocket programming]$ cat number.txt<br>1<br>3<br>5<br>2<br>4<br>[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt<br>[rocrocket@rocrocket programming]$ cat number.txt<br>5<br>4<br>3<br>2<br>1</p>
<p><strong>5 sort的-n选项</strong></p>
<p>你有没有遇到过10比2小的情况。我反正遇到过。出现这种情况是由于排序程序将这些数字按字符来排序了，排序程序会先比较1和2，显然1小，所以就将10放在2前面喽。这也是sort的一贯作风。</p>
<p>我们如果想改变这种现状，就要使用-n选项，来告诉sort，&#8220;要以数值来排序&#8221;！</p>
<p>[rocrocket@rocrocket programming]$ cat number.txt<br>1<br>10<br>19<br>11<br>2<br>5<br>[rocrocket@rocrocket programming]$ sort number.txt<br>1<br>10<br>11<br>19<br>2<br>5<br>[rocrocket@rocrocket programming]$ sort -n number.txt<br>1<br>2<br>5<br>10<br>11<br>19</p>
<p><strong>6 sort的-t选项和-k选项</strong></p>
<p>如果有一个文件的内容是这样：</p>
<p>[rocrocket@rocrocket programming]$ cat facebook.txt<br>banana:30:5.5<br>apple:10:2.5<br>pear:90:2.3<br>orange:20:3.4</p>
<p>这个文件有三列，列与列之间用冒号隔开了，第一列表示水果类型，第二列表示水果数量，第三列表示水果价格。</p>
<p>那么我想以水果数量来排序，也就是以第二列来排序，如何利用sort实现？</p>
<p>幸好，sort提供了-t选项，后面可以设定间隔符。（是不是想起了cut和paste的-d选项，共鸣～～）</p>
<p>指定了间隔符之后，就可以用-k来指定列数了。</p>
<p>[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt<br>apple:10:2.5<br>orange:20:3.4<br>banana:30:5.5<br>pear:90:2.3</p>
<p>我们使用冒号作为间隔符，并针对第二列来进行数值升序排序，结果很令人满意。</p>
<p><strong>7 其他的sort常用选项</strong></p>
<p>-f会将小写字母都转换为大写字母来进行比较，亦即忽略大小写</p>
<p>-c会检查文件是否已排好序，如果乱序，则输出第一个乱序的行的相关信息，最后返回1</p>
<p>-C会检查文件是否已排好序，如果乱序，不输出内容，仅返回1</p>
<p>-M会以月份来排序，比如JAN小于FEB等等</p>
<p>-b会忽略每一行前面的所有空白部分，从第一个可见字符开始比较。</p>
<p><span style="COLOR: #800000"><strong>未完待续，敬请期待：《sort命令的k选项大讨论》</strong></span></p>
<img src ="http://www.cppblog.com/prayer/aggbug/115186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-05-12 13:32 <a href="http://www.cppblog.com/prayer/archive/2010/05/12/115186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell预定义变量</title><link>http://www.cppblog.com/prayer/archive/2010/04/12/112366.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 12 Apr 2010 11:11:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/04/12/112366.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/112366.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/04/12/112366.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/112366.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/112366.html</trackback:ping><description><![CDATA[预定义变量和环境变量相类似，也是在Shell一开始时就定义了的变量。所不同的是，用户只能根据Shell的定义来使用这些变量，而不能重定义它。所有预定义变量都是由$符和另一个符号组成的，常用的Shell预定义变量有：<br>
$# 位置参数的数量。<br>
$* 所有位置参数的内容。<br>
$? 命令执行后返回的状态。<br>
$$ 当前进程的进程号。<br>
$! 后台运行的最后一个进程号。<br>
$0 当前执行的进程名。<br>
其中，$?用于检查上一个命令执行是否正确。（在Linux中，命令退出状态为0表示该命令正确执行，任何非0值表示命令出错。）<br>
$$变量最常见的用途是用做暂存文件的名字以保证暂存文件不会重复。<img src ="http://www.cppblog.com/prayer/aggbug/112366.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-04-12 19:11 <a href="http://www.cppblog.com/prayer/archive/2010/04/12/112366.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>怎样向awk中传入shell变量值</title><link>http://www.cppblog.com/prayer/archive/2010/04/12/112365.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 12 Apr 2010 11:10:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/04/12/112365.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/112365.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/04/12/112365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/112365.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/112365.html</trackback:ping><description><![CDATA[<p>假设当前目录下有a.log b.log二个文件，利用awk打印出其文件名，脚本如下：</p>
<p>#! /bin/bash<br>
for file in *.log<br>
do<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; awk 'BEGIN{var=" ' "$file" ' "}END{print var;}' "$file"<br>
done</p>
<p><strong><span style="color: #0000ff;">在这里最让人混淆的是单引号和双引号</span>
</strong>
</p>
<p><br>
<strong>我们可以利用bash -x test.sh来执行脚本，其会将脚本中的shell变量展开，便于调试</strong>
</p>
<p><strong>&#8217;单引号中除（&#8217;）都为原本字符，没有特殊意义</strong>
</p>
<p><strong>"双引号中除（</strong>
<strong>$`"）</strong>
<strong>都为原本字符，没有特殊意义</strong>
</p>
<p><strong>因此，上述可以展开为:</strong>
</p>
<p><strong>第一次：<br>
</strong>
</p>
<p><strong> awk 'BEGIN{var="a.log"}END{print var;}&#8216; a.log</strong>
</p>
<p><strong>第二次：<br>
</strong>
</p>
<p><strong>awk 'BEGIN{var="b.log"}END{print var;}&#8216; b.log</strong>
</p>
<p>如果将其写成 awk 'BEGIN{var=' "$file" '}END{print var;}' "$file"，则展开为：</p>
<p><strong>第一次：<br>
</strong>
</p>
<p><strong> awk 'BEGIN{var=a.log}END{print var;}&#8216; a.log</strong>
</p>
<p><strong>第二次：<br>
</strong>
</p>
<p><strong>awk 'BEGIN{var=b.log}END{print var;}&#8216; b.log</strong>
</p>
<p><strong>会报错，因为awk中字符串要用双引号括起来</strong>
</p>
<p><strong><br>
</strong>
</p>
<p><strong>将其分解成以下这样，便于理解：</strong>
</p>
<p><strong></strong>
'BEGIN{var=" '&nbsp;&nbsp;&nbsp; "$file" &nbsp; &nbsp; ' "}END{print var;}'&nbsp; 这三部分为字符串连接关系</p> <img src ="http://www.cppblog.com/prayer/aggbug/112365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-04-12 19:10 <a href="http://www.cppblog.com/prayer/archive/2010/04/12/112365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eval用法三例,与大家分享,很有用o !    对字符串两次解析。</title><link>http://www.cppblog.com/prayer/archive/2010/03/28/110744.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Sun, 28 Mar 2010 09:49:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/03/28/110744.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/110744.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/03/28/110744.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/110744.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/110744.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p>## eval用法三例 ##<br>## shell:/bin/sh ##<br>## yhc 2002.09.26 18:00 ##</p>
<p>#例一:<br>#寻找合符条件的变量名,然后将该变量的值赋予另一变量<br>v1=aaa<br>v2=bbb<br>c=1<br>if [ $c -eq 1 ]<br>then<br>&nbsp; vname=v$c&nbsp;&nbsp; #找到符合条件的变量名为v1<br>&nbsp; eval vvv="$"$vname ; echo vvv: $vvv&nbsp;&nbsp;&nbsp; #将变量v1的值赋予vvv,即,使vvv=aaa<br>&nbsp; eval vvv='$'$vname ; echo vvv: $vvv&nbsp;&nbsp;&nbsp; #将变量v1的值赋予vvv,即,使vvv=aaa<br>&nbsp;#eval vvv=$$vname&nbsp;&nbsp; ; echo vvv: $vvv&nbsp;&nbsp;&nbsp; #错误用法<br>fi</p>
<p><br>#例二:#以变量v1的值aaa作为变量名,将变量vaaa的值赋予这一新定义的变量aaa<br>v1=aaa ; vaaa="This is aaa"<br>#eval $v1=$vaaa&nbsp;&nbsp;&nbsp; ; echo aaa: $aaa&nbsp;&nbsp;&nbsp; #错误用法<br>#eval $v1="$vaaa"&nbsp; ; echo aaa: $aaa&nbsp;&nbsp;&nbsp; #错误用法<br>eval $v1='$vaaa'&nbsp;&nbsp; ; echo aaa: $aaa</p>
<p><br>#例三:<br>#以变量v1的值aaa作为变量名,并将变量名字串作为值赋予自身<br>v1=aaa ; vaaa="This is aaa"<br>eval $v1=$v1&nbsp;&nbsp; ; echo aaa: $aaa&nbsp;&nbsp;&nbsp; #与例二的错误用法不同,这一用法是正确的<br>eval $v1="$v1" ; echo aaa: $aaa&nbsp;&nbsp;&nbsp; #与例二的错误用法不同,这一用法是正确的<br>eval $v1='$v1' ; echo aaa: $aaa</p>
<p>该文章转载自[程序人生]：&lt;a href="<a href="http://www.procedurelife.com/technical/SHELL/content/lbkjf.html">http://www.procedurelife.com/technical/SHELL/content/lbkjf.html</a>" target="_blank"&gt;http://www.procedurelife.com/technical/SHELL/content/lbkjf.html&lt;/a&gt;<br><br><br><br></p>
<img src ="http://www.cppblog.com/prayer/aggbug/110744.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-03-28 17:49 <a href="http://www.cppblog.com/prayer/archive/2010/03/28/110744.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell中trap捕捉到信号的处理</title><link>http://www.cppblog.com/prayer/archive/2010/03/28/110743.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Sun, 28 Mar 2010 09:42:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/03/28/110743.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/110743.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/03/28/110743.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/110743.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/110743.html</trackback:ping><description><![CDATA[<p>一. trap捕捉到信号之后，可以有三种反应方式：<br><br>　　(1)执行一段程序来处理这一信号<br><br>　　(2)接受信号的默认操作<br><br>　　(3)忽视这一信号<br><br>　　二. trap对上面三种方式提供了三种基本形式：<br><br>　　第一种形式的trap命令在shell接收到signal list清单中数值相同的信号时，将执行双<br><br>　　引号中的命令串。<br><br>　　trap 'commands' signal-list<br><br>　　trap "commands" signal-list<br><br>　　为了恢复信号的默认操作，使用第二种形式的trap命令：<br><br>　　trap signal-list<br><br>　　第三种形式的trap命令允许忽视信号<br><br>　　trap " " signal-list</p>
<p>&#160;</p>
<p>&#160;</p>
<p>注意：<br><br>　　(1) 对信号11(段违例)不能捕捉，因为shell本身需要捕捉该信号去进行内存的转储。<br><br>　　(2) 在trap中可以定义对信号0的处理(实际上没有这个信号)， shell程序在其终止(如<br><br>　　执行exit语句)时发出该信号。<br><br>　　(3) 在捕捉到signal-list中指定的信号并执行完相应的命令之后， 如果这些命令没有<br><br>　　将shell程序终止的话，shell程序将继续执行收到信号时所执行的命令后面的命令，这样将<br><br>　　很容易导致shell程序无法终止。<br><br>　　另外，在trap语句中，单引号和双引号是不同的，当shell程序第一次碰到trap语句时，<br><br>　　将把commands中的命令扫描一遍。此时若commands是用单引号括起来的话，那么shell不会<br><br>　　对commands中的变量和命令进行替换， 否则commands中的变量和命令将用当时具体的值来</p>
<p>&#160;</p>
<p>kill -l可以列出系统的信号</p>
<p>通常我们需要忽略的信号有四个，即：HUP, INT, QUIT, TSTP，也就是信号1, 2, 3, 24 <br>使用这样的语句可以使这些中断信号被忽略： <br>trap "" 1 2 3 24 或 trap "" HUP INT QUIT TSTP <br>用 trap ：1 2 3 24 或 trap HUP INT QUIT TSTP使其回复默认值。 <br>用stty -a可以列出中断信号与键盘的对应，分别执行上面的命令后，运行 <br>tail -f /etc/passwd, 然后尝试用键盘中断，试试两种情况（默认和忽略）下有何不同。 <br>更方便的是我们可以用在shell中用trap定义我们自己的信号处理程序</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
<div>#!/bin/bash<br>#scriptname: trapping<br>#can use the singnal numbers of bash abbreviations seen<br>#below. Cannot use SIGINT ,SIGOUIT ,etc</div>
<div>trap 'echo Control-c will not terminate $0. ' INT<br>trap 'echo Control-\ will not terminate $0. ' QUIT<br>trap 'echo Control-Z will not terminate $0. ' TSTP</div>
<div>echo "Enter any string after the prompt. When you are ready to exit ,type \"stop\"."</div>
<div>while true<br>do</div>
<div>echo -n "Go ahead ...&gt;"<br>read<br>if [[ $reply==[sS]top ]]<br>then<br>&nbsp;&nbsp; break<br>fi<br>done</div>
<img src ="http://www.cppblog.com/prayer/aggbug/110743.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-03-28 17:42 <a href="http://www.cppblog.com/prayer/archive/2010/03/28/110743.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>awk内置字符串函数详解</title><link>http://www.cppblog.com/prayer/archive/2010/03/28/110742.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Sun, 28 Mar 2010 09:14:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/03/28/110742.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/110742.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/03/28/110742.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/110742.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/110742.html</trackback:ping><description><![CDATA[<div>awk提供了许多强大的字符串函数，见下表：<br>awk内置字符串函数<br>
<table class=zeroBorder id=c-nq style="WIDTH: 458px; HEIGHT: 298px" cellSpacing=0 cellPadding=3 border=0>
    <tbody>
        <tr>
        </tr>
        <tr>
            <td width="50%">gsub(r,s)</td>
            <td width="50%">在整个$0中用s替代r </td>
        </tr>
        <tr>
            <td width="50%">gsub(r,s,t)</td>
            <td width="50%">在整个t中用s替代r</td>
        </tr>
        <tr>
            <td width="50%">index(s,t)<span></span><br></td>
            <td width="50%">返回s中字符串t的第一位置</td>
        </tr>
        <tr>
            <td width="50%">length(s)<br></td>
            <td width="50%">返回s长度</td>
        </tr>
        <tr>
            <td width="50%">match(s,r)<br></td>
            <td width="50%">测试s是否包含匹配r的字符串</td>
        </tr>
        <tr>
            <td width="50%">split(s,a,fs)</td>
            <td width="50%"><span></span>在fs上将s分成序列a </td>
        </tr>
        <tr>
            <td width="50%">sprint(fmt,exp)</td>
            <td width="50%">返回经fmt格式化后的exp </td>
        </tr>
        <tr>
            <td width="50%">sub(r,s)<br></td>
            <td width="50%">用$0中最左边最长的子串代替s </td>
        </tr>
        <tr>
            <td width="50%">substr(s,p)</td>
            <td width="50%">返回字符串s中从p开始的后缀部分</td>
        </tr>
        <tr>
            <td width="50%">substr(s,p,n)<br></td>
            <td width="50%">返回字符串s中从p开始长度为n的后缀部分</td>
        </tr>
    </tbody>
</table>
详细说明一下各个函数的使用方法。<br><span class=fullpost><br>gsub函数有点类似于sed查找和替换。它允许替换一个字符串或字符为另一个字符串或字符，并以正则表达式的形式执行。第一个函数作用于记录$0，第二个gsub函数允许指定目标，然而，如果未指定目标，缺省为$0。<br>index(s,t)函数返回目标字符串s中查询字符串t的首位置。length函数返回字符串s字符<br>长度。match函数测试字符串s是否包含一个正则表达式r定义的匹配。split使用域分隔符fs将<br>字符串s划分为指定序列a。sprint函数类似于printf函数(以后涉及)，返回基本输出格式fmt的<br>结果字符串exp。sub(r,s)函数将用s替代$0中最左边最长的子串，该子串被(r)匹配。<br>sub(s,p)返回字符串s在位置p后的后缀。substr(s,p,n)同上，并指定子串长度为n。<br>现在看一看awk中这些字符串函数的功能。<br><br><span style="FONT-WEIGHT: bold">1.gsub</span><br>要在整个记录中替换一个字符串为另一个，使用正则表达式格式，/目标模式/，替换模式<br>/。例如改变学生序号4842到4899：<br><br>$ awk 'gsub('4842/, 4899) {print $0}' grade.txt<br>J.Troll 07/99 4899 Brown-3 12 26 26<br><br><span style="FONT-WEIGHT: bold">2.index</span><br>查询字符串s中t出现的第一位置。必须用双引号将字符串括起来。例如返回目标字符串<br>Bunny中ny出现的第一位置，即字符个数。<br><br>$ awk 'BEGIN {print index("Bunny", "ny")} grade.txt<br>4<br><br><span style="FONT-WEIGHT: bold">3.length</span><br>返回所需字符串长度，例如检验字符串J.Troll返回名字及其长度，即人名构成的字符个<br>数。<br><br>$ awk '$1=="J.Troll" {print length($1) " "$1}' grade.txt<br>7 J.Troll<br><br>还有一种方法，这里字符串加双引号。<br><br>$ awk 'BEGIN {print length("A FEW GOOD MEN")}'<br>14<br><br><span style="FONT-WEIGHT: bold">4.match</span><br>match测试目标字符串是否包含查找字符的一部分。可以对查找部分使用正则表达式,返<br>回值为成功出现的字符排列数。如果未找到,返回0,第一个例子在ANCD中查找d。因其不<br>存在,所以返回0。第二个例子在ANCD中查找D。因其存在,所以返回ANCD中D出现的首位<br>置字符数。第三个例子在学生J.Lulu中查找u。<br><br>$ awk '{BEGIN {print match("ANCD", /d/)}'<br>0<br>$ awk '{BEGIN {print match("ANCD", /C/)}'<br>3<br>$ awk '$1=="J.Lulu" {print match($1, "u")} grade.txt<br>4<br><br><span style="FONT-WEIGHT: bold">5.split</span><br>使用split返回字符串数组元素个数。工作方式如下：如果有一字符串,包含一指定分隔<br>符-,例如AD2-KP9-JU2-LP-1,将之划分成一个数组。使用split,指定分隔符及数组名。此<br>例中,命令格式为("AD2-KP9-JU2-LP-1",parts_array,"-"),split然后返回数组下标数,这<br>里结果为4。<br>还有一个例子使用不同的分隔符。<br><br>$ awk '{BEGIN {print split("123#456#678", myarray, "#")}'<br>3<br><br>这个例子中,split返回数组myarray的下标数。数组myarray取值如下：<br><br>Myarray[1]="123"<br>Myarray[2]="456"<br>Myarray[3]="789"<br><br><span style="FONT-WEIGHT: bold">6.sub</span><br>使用sub发现并替换模式的第一次出现位置。字符串STR包含&#8216;popedpopopill&#8217;,执行下<br>列sub命令sub(/op/,"op",STR)。模式op第一次出现时,进行替换操作,返回结果如下：<br>&#8216;pOPedpopepill&#8217;。<br>假如grade.txt文件中,学生J.Troll的记录有两个值一样,&#8220;目前级别分&#8221;与&#8220;最高级别分&#8221;。只<br>改变第一个为29,第二个仍为24不动,操作命令为sub(/26/,"29",$0),只替换第一个出现<br>24的位置。<br><br>$ awk '$1=="J.Troll" sub(/26/, "29", $0)' grade.txt<br>L.Troll 07/99 4842 Brown-3 12 29 26<br>L.Transley 05/99 4712 Brown-2 12 30 28<br><br><span style="FONT-WEIGHT: bold">7.substr</span><br>substr是一个很有用的函数。它按照起始位置及长度返回字符串的一部分。例子如下：<br><br>$ awk '$1=="L.Transley" {print substr($1, 1,5)}' grade.txt<br>L.Tan<br>上面例子中,指定在域1的第一个字符开始,返回其前面5个字符。<br>如果给定长度值远大于字符串长度， awk将从起始位置返回所有字符，要抽取L.Tansley的姓,只需从第3个字符开始返回长度为7。可以输入长度99,awk返回结果相同。<br><br>$ awk '{$1=="L.Transley" {print substr($1, 3,99)}' grade.txt<br>Transley<br><br>substr的另一种形式是返回字符串后缀或指定位置后面字符。这里需要给出指定字符串及其返回字串的起始位置。例如,从文本文件中抽取姓氏,需操作域1,并从第三个字符开始：<br><br>$ awk '{print substr($1, 3)}' grade.txt<br>Troll<br>Transley<br><br>还有一个例子,在BEGIN部分定义字符串,在END部分返回从第t个字符开始抽取的子串。<br><br>$ awk '{BEGIN STR="A FEW GOOD MEN"} END {print substr(STR,7)) grade.txt<br>GOOD MEN<br><br><span style="FONT-WEIGHT: bold">8.从shell中向awk传入字符串 </span><br>awk脚本大多只有一行,其中很少是字符串表示的,这一点通过将变量传入awk命令行会变得很容易。现就其基本原理讲述一些例子。<br>使用管道将字符串stand-by传入awk,返回其长度。<br><br>$ echo "Stand-by" | awk '{print length($0)}'<br>8<br><br>设置文件名为一变量,管道输出到awk,返回不带扩展名的文件名。<br><br>$ STR="mydoc.txt"<br>$ echo $STR | awk '{print subst($STR, 1, 5)}'<br>mydoc<br><br>设置文件名为一变量,管道输出到awk,只返回其扩展名。<br>$ STR="mydoc.txt"<br>$ echo $STR | awk '{print substr($STR, 7)}'<br>txt<br></span></div>
<img src ="http://www.cppblog.com/prayer/aggbug/110742.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-03-28 17:14 <a href="http://www.cppblog.com/prayer/archive/2010/03/28/110742.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>