﻿<?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++博客-beautykingdom-随笔分类-Shell</title><link>http://www.cppblog.com/beautykingdom/category/8562.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 07 Jul 2011 15:01:15 GMT</lastBuildDate><pubDate>Thu, 07 Jul 2011 15:01:15 GMT</pubDate><ttl>60</ttl><item><title>shell从1+到100</title><link>http://www.cppblog.com/beautykingdom/archive/2010/10/28/131607.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Thu, 28 Oct 2010 03:12:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/10/28/131607.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/131607.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/10/28/131607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/131607.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/131607.html</trackback:ping><description><![CDATA[
<div>第一种方法：</div><div>&nbsp;#!/bin/bash</div><div>echo -e "\t${!#}"</div><div>for (( i = 0; i &lt; 100; i++ ))</div><div>do</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;result=$[ ${result} + ${i} ]</div><div>done</div><div>echo $result</div><div>第二种方法：</div><div><span style="border-collapse: collapse; font-family: song, Verdana; font-size: 14px; line-height: 22px; ">seq -s"+" 1 100|bc</span></div><div>第三种方法：</div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">s=0</span></div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; "></span><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">for ((i=1;i&lt;=100;i++)) ; do</span></div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; "></span><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">&nbsp;&nbsp; &nbsp;s=`expr $s + $i`</span></div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; "></span><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">done</span></div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; "></span><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">echo $s</span></div><div>第四种方法：</div><div><table cellspacing="0" cellpadding="0" style="word-wrap: break-word; empty-cells: show; border-collapse: collapse; line-height: normal; table-layout: fixed; margin-left: 1px; font-family: song, Verdana; font-size: 12px; width: 910px; "><tbody style="word-wrap: break-word; line-height: normal; "><tr style="word-wrap: break-word; line-height: normal; "><td class="t_msgfont" id="postmessage_12782032" style="word-wrap: break-word; color: rgb(0, 0, 0); font: normal normal normal 12px/normal song, Verdana; line-height: 1.6em; font-size: 14px; ">#!/bin/sh<br style="word-wrap: break-word; line-height: normal; ">s=0<br style="word-wrap: break-word; line-height: normal; ">for i in `seq 1 100`<br style="word-wrap: break-word; line-height: normal; ">do<br style="word-wrap: break-word; line-height: normal; ">s=`expr $s + $i`<br style="word-wrap: break-word; line-height: normal; ">done<br style="word-wrap: break-word; line-height: normal; ">echo $s<br><br>第五种方法：<br><span  style="line-height: normal; font-size: 12px; "><table cellspacing="0" cellpadding="0" style="word-wrap: break-word; empty-cells: show; border-collapse: collapse; line-height: normal; table-layout: fixed; margin-left: 1px; width: 898px; "><tbody style="word-wrap: break-word; line-height: normal; "><tr style="word-wrap: break-word; line-height: normal; "><td class="t_msgfont" id="postmessage_12783476" style="word-wrap: break-word; color: rgb(0, 0, 0); font: normal normal normal 12px/normal song, Verdana; line-height: 1.6em; font-size: 14px; ">echo {1..100}|sed 's/ /+/g'|bc<br><br><br></td></tr></tbody></table></span>from：<br><a href="http://bbs.chinaunix.net/thread-1777298-1-1.html">http://bbs.chinaunix.net/thread-1777298-1-1.html</a></td></tr></tbody></table></div>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/131607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-10-28 11:12 <a href="http://www.cppblog.com/beautykingdom/archive/2010/10/28/131607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>文本过滤工具GREP</title><link>http://www.cppblog.com/beautykingdom/archive/2010/06/01/116859.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 01 Jun 2010 01:48:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/06/01/116859.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/116859.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/06/01/116859.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/116859.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/116859.html</trackback:ping><description><![CDATA[ grep: <br>
传统的 grep 程序, 在没有参数的情况下, 只输出符合 RE 字符串之句子. 常见参数如下: <br>
-v: 逆反模示, 只输出"不含" RE 字符串之句子. <br>
-r: 递归<span href="http://bbs.chinaunix.net/tag.php?name=%C4%A3%CA%BD" onclick="tagshow(event)" class="t_tag">模式</span>, 可同时处理所有层级子目录里的文件. <br>
-q: 静默模式, 不输出任何结果(stderr 除外. 常用以获取 return value, 符合为 true, 否则为 false .) <br>
-i: 忽略大小写. <br>
-w: 整词比对, 类似 \&lt;word\&gt; . <br>
-n: 同时输出行号. <br>
-c: 只输出符合比对的行数. <br>
-l: 只输出符合比对的文件名称. <br>
-o: 只输出符合 RE 的字符串. (gnu 新版独有, 不见得所有版本都支持.) <br>
-E: 切换为 egrep . <br>
<br>
* egrep: <br>
为 grep 的扩充版本, 改良了许多传统 grep 不能或不便的操作. 比方说: <br>
- grep 之下不支持 ? 与 + 这两种 modifier, 但 egrep 则可. <br>
- grep 不支持 a|b 或 (abc|xyz) 这类"或一"比对, 但 egrep 则可. <br>
- grep 在处理 {n,m} 时, 需用 \{ 与 \} 处理, 但 egrep 则不需. <br>
诸如此类的... 我个人会建议能用 egrep 就不用 grep 啦... ^_^ <br>
<br>
* fgrep: <br>
不作 RE 处理, 表达式仅作一般字符串处理, 所有 meta 均失去功能.<br><br><strong>单引号双引号<br>
在g r e p命令中输入字符串参数时，最好将其用双引号括起来。</strong><br>
<strong>在调用模式匹配时，应使用单引号。</strong><br>
<br>开始讨论之前，先生成一个文件，插入一段文本，并在每列后加入&lt; Ta b &gt;键，g r e p命令示例中绝大多数将以此为例，其命名为d
a t a . . f。生成一个文件，d a t a . f的记录结构如下：<br>
<br>
<br><br>
<div class="msgbody">
<div class="msgheader">QUOTE:</div>
<div class="msgborder">第1列：城市位置编号。<br>
第2列：月份。<br>
第3列：存储代码及出库年份。<br>
第4列：产品代号。<br>
第5列：产品统一标价。<br>
第6列：标识号。<br>
第7列：合格数量。</div>
</div>
<br><br>
<br>
<strong>文件内容如下：</strong><br>
<div id="code1">
<ol>
    <li>$ cat data.f<br>
    </li>
    <li>48&nbsp; &nbsp;&nbsp; &nbsp;Dec&nbsp; &nbsp;&nbsp;&nbsp;3BC1977 LPSX&nbsp; &nbsp; 68.00&nbsp; &nbsp;LVX2A&nbsp; &nbsp;138<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;Sept&nbsp; &nbsp; 5AP1996 USP&nbsp; &nbsp;&nbsp;&nbsp;65.00&nbsp; &nbsp;LVX2C&nbsp; &nbsp;189<br>
    </li>
    <li>47&nbsp; &nbsp;&nbsp; &nbsp;Oct&nbsp; &nbsp;&nbsp;&nbsp;3ZL1998 LPSX&nbsp; &nbsp; 43.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;512<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>484&nbsp; &nbsp;&nbsp;&nbsp;nov&nbsp; &nbsp;&nbsp;&nbsp;7PL1996 CAD&nbsp; &nbsp;&nbsp;&nbsp;49.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;234<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;may&nbsp; &nbsp;&nbsp;&nbsp;5PA1998 USP&nbsp; &nbsp;&nbsp;&nbsp;37.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;644<br>
    </li>
    <li>216&nbsp; &nbsp;&nbsp;&nbsp;sept&nbsp; &nbsp; 3ZL1998 USP&nbsp; &nbsp;&nbsp;&nbsp;86.00&nbsp; &nbsp;KVM9E&nbsp; &nbsp;234</li>
</ol>
</div>
<br><strong>1、查询多个文件</strong><br>
在所有文件中查询单词&#8220; sort it&#8221;<br>
<div class="blockcode">
<div id="code2">
<ol>
    <li>$ grep "sort it" *</li>
</ol>
</div>
<em onclick="copycode($('code2'));"></em></div>
<br>
<br>
<strong>2、 行匹配</strong><br>
1)显示包含&#8220;4 8&#8221;字符串的文本：<br>
<div class="blockcode">
<div id="code3">
<ol>
    <li>$ grep&nbsp;&nbsp;"48"data.f</li>
</ol>
</div>
<em onclick="copycode($('code3'));"></em></div>
<br>
<br>
<strong>2)输出匹配行的总数</strong><br>
<div class="blockcode">
<div id="code4">
<ol>
    <li>$ grep -c "48"data.f<br>
    </li>
    <li>4</li>
</ol>
</div>
<em onclick="copycode($('code4'));"></em></div>
<br>
g r e p返回数字4，表示：包含字符串&#8220;4 8&#8221;的有4行。<br>
<br>
<strong>3)行数</strong><br>
显示满足匹配模式的所有行行数：<br>
<div class="blockcode">
<div id="code5">
<ol>
    <li>$ grep -n "48"data.f</li>
</ol>
</div>
<em onclick="copycode($('code5'));"></em></div>
<br>
行数在输出第一列，后跟包含4 8的每一匹配行。<br>
<br>
<strong>4)显示非匹配行</strong><br>
显示所有不包含4 8的各行<br>
<div class="blockcode">
<div id="code6">
<ol>
    <li>$ grep -v "48"data.f</li>
</ol>
</div>
<em onclick="copycode($('code6'));"></em></div>
<br>
<strong>5)精确匹配</strong><br>
可能大家已注意到，在上一例中，抽取字符串&#8220; 4 8&#8221;，返回结果包含诸如4 8 4和4 8 3等包含&#8220;4
8&#8221;的其他字符串，实际上应精确抽取只包含4 8的各行。<br>
使用g r e p抽取精确匹配的一种更有效方式是在抽取字符串后加\ &gt;。假定现在精确抽取4 8，方法如下：<br>
<div class="blockcode">
<div id="code7">
<ol>
    <li>$grep "48\&gt;" data.f</li>
</ol>
</div>
<em onclick="copycode($('code7'));"></em></div>
<br>
<div class="msgbody">
<div class="msgheader">QUOTE:</div>
<div class="msgborder">另一种方法我试过，好像不行：<br>
注意在每个匹配模式中抽取字符串后有一个&lt; Ta b &gt;键，所以应操作如下：<br>
&lt; Ta b &gt;表示点击t a b键。<br>
$grep "48&lt;tab&gt;" data.f</div>
</div>
<br>
<strong>6)大小写敏感</strong><br>
缺省情况下， g r e p是大小写敏感的，如要查询大小写不敏感字符串，必须使用- i开关。在d a t a . f文件中有月份字符S e p
t，既有大写也有小写，要取得此字符串大小写不敏感查询，方法如下：<br>
<div class="blockcode">
<div id="code8">
<ol>
    <li>$grep -i "48" data.f</li>
</ol>
</div>
<em onclick="copycode($('code8'));"></em></div>
<br><strong>grep和正则表达式</strong><br>
<br>
使用正则表达式使模式匹配加入一些规则，因此可以在抽取信息中加入更多选择。使用正则表达式时最好用单引号括起来，这样可以防止g r e
p中使用的专有模式与一些s h e l l命令的特殊方式相混淆。<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br>
<strong>1、模式范围</strong><br>
抽取代码为4 8 4和4 8 3的城市位置，可以使用[ ]来指定字符串范围。<br>
<div class="blockcode">
<div id="code9">
<ol>
    <li>$ grep "48[34]" data.f<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;Sept&nbsp; &nbsp; 5AP1996 USP&nbsp; &nbsp;&nbsp;&nbsp;65.00&nbsp; &nbsp;LVX2C&nbsp; &nbsp;189<br>
    </li>
    <li>484&nbsp; &nbsp;&nbsp;&nbsp;nov&nbsp; &nbsp;&nbsp;&nbsp;7PL1996 CAD&nbsp; &nbsp;&nbsp;&nbsp;49.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;234<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;may&nbsp; &nbsp;&nbsp;&nbsp;5PA1998 USP&nbsp; &nbsp;&nbsp;&nbsp;37.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;644&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
<strong>2、不匹配行首</strong><br>
使行首不是4或8，可以在方括号中使用^记号。<br>
<div class="blockcode">
<div id="code10">
<ol>
    <li>$ grep "^[^48]" data.f<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>216&nbsp; &nbsp;&nbsp;&nbsp;sept&nbsp; &nbsp; 3ZL1998 USP&nbsp; &nbsp;&nbsp;&nbsp;86.00&nbsp; &nbsp;KVM9E&nbsp; &nbsp;234</li>
</ol>
</div>
<em onclick="copycode($('code10'));"></em></div>
<strong>如果是字符串48</strong><br>
<div class="blockcode">
<div id="code11">
<ol>
    <li>$ grep -v "^[^48]"
    data.f&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
<strong>3、设置大小写</strong><br>
使用- i开关可以屏蔽月份S e p t的大小写敏感<br>
<div class="blockcode">
<div id="code12">
<ol>
    <li>[sam@chenwy sam]$ grep
    -i "sept" data.f<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;Sept&nbsp; &nbsp; 5AP1996 USP&nbsp; &nbsp;&nbsp;&nbsp;65.00&nbsp; &nbsp;LVX2C&nbsp; &nbsp;189<br>
    </li>
    <li>216&nbsp; &nbsp;&nbsp;&nbsp;sept&nbsp; &nbsp; 3ZL1998 USP&nbsp; &nbsp;&nbsp;&nbsp;86.00&nbsp; &nbsp;KVM9E&nbsp; &nbsp;234<em onclick="copycode($('code12'));"></em>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
也可以用另一种方式[ ]模式抽取各行包含S e p t和s e p t的所有信息。<br>
<div class="blockcode">
<div id="code13">
<ol>
    <li>[sam@chenwy sam]$ grep
    '[sS]ept' data.f</li>
</ol>
</div>
<em onclick="copycode($('code13'));"></em></div>
如果要抽取包含S e p t的所有月份，不管其大小写，并且此行包含字符串483，可以使用管道命令，即符号&#8220;|&#8221;左边命令的输出作为&#8220;
|&#8221;右边命令的输入。举例如下：<br>
<div class="blockcode">
<div id="code14">
<ol>
    <li>[sam@chenwy sam]$ grep
    '[sS]ept' data.f | grep 48<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;Sept&nbsp; &nbsp; 5AP1996 USP&nbsp; &nbsp;&nbsp;&nbsp;65.00&nbsp; &nbsp;LVX2C&nbsp; &nbsp;189</li>
</ol>
</div>
<em onclick="copycode($('code14'));"></em></div>
不必将文件名放在第二个g r e p命令中，因为其输入信息来自于第一个g r e p命令的输出<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br>
<strong>4、匹配任意字符</strong><br>
如果抽取以K开头，以D结尾的所有代码，可使用下述方法，因为已知代码长度为5个字符：<br>
<div class="blockcode">
<div id="code15">
<ol>
    <li>[sam@chenwy sam]$ grep
    'K...D' data.f<br>
    </li>
    <li>47&nbsp; &nbsp;&nbsp; &nbsp;Oct&nbsp; &nbsp;&nbsp;&nbsp;3ZL1998 LPSX&nbsp; &nbsp; 43.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;512<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;may&nbsp; &nbsp;&nbsp;&nbsp;5PA1998 USP&nbsp; &nbsp;&nbsp;&nbsp;37.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;644<em onclick="copycode($('code15'));"></em>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
将上述代码做轻微改变，头两个是大写字母，中间两个任意，并以C结尾：<br>
<div class="blockcode">
<div id="code16">
<ol>
    <li>[sam@chenwy sam]$ grep
    '[A-Z]..C' data.f<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;Sept&nbsp; &nbsp; 5AP1996 USP&nbsp; &nbsp;&nbsp;&nbsp;65.00&nbsp; &nbsp;LVX2C&nbsp; &nbsp;189<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>484&nbsp; &nbsp;&nbsp;&nbsp;nov&nbsp; &nbsp;&nbsp;&nbsp;7PL1996 CAD&nbsp; &nbsp;&nbsp;&nbsp;49.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;234</li>
</ol>
</div>
<em onclick="copycode($('code16'));"></em></div>
<strong>5、日期查询</strong><br>
一个常用的查询模式是日期查询。先查询所有以5开始以1 9 9 6或1 9 9 8结尾的所有记录。使用模式5 . . 1 9 9 [ 6 , 8
]。这意味着第一个字符为5，后跟两个点，接着是1 9 9，剩余两个数字是6或8。<br>
<div class="blockcode">
<div id="code17">
<ol>
    <li>[sam@chenwy sam]$ grep
    '5..199[6,8]' data.f<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;Sept&nbsp; &nbsp; 5AP1996 USP&nbsp; &nbsp;&nbsp;&nbsp;65.00&nbsp; &nbsp;LVX2C&nbsp; &nbsp;189<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;may&nbsp; &nbsp;&nbsp;&nbsp;5PA1998 USP&nbsp; &nbsp;&nbsp;&nbsp;37.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;644<em onclick="copycode($('code17'));"></em>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
<strong>6、范围组合</strong><br>
必须学会使用[ ]抽取信息。假定要取得城市代码，第一个字符为0-9，第二个字符在0到5之间，第三个字符在0到6之间，使用下列模式即可实现。<br>
<div class="blockcode">
<div id="code18">
<ol>
    <li>[sam@chenwy sam]$ grep
    '[0-9][0-5[0-6]' data.f<br>
    </li>
    <li>48&nbsp; &nbsp;&nbsp; &nbsp;Dec&nbsp; &nbsp;&nbsp;&nbsp;3BC1977 LPSX&nbsp; &nbsp; 68.00&nbsp; &nbsp;LVX2A&nbsp; &nbsp;138<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;Sept&nbsp; &nbsp; 5AP1996 USP&nbsp; &nbsp;&nbsp;&nbsp;65.00&nbsp; &nbsp;LVX2C&nbsp; &nbsp;189<br>
    </li>
    <li>47&nbsp; &nbsp;&nbsp; &nbsp;Oct&nbsp; &nbsp;&nbsp;&nbsp;3ZL1998 LPSX&nbsp; &nbsp; 43.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;512<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>484&nbsp; &nbsp;&nbsp;&nbsp;nov&nbsp; &nbsp;&nbsp;&nbsp;7PL1996 CAD&nbsp; &nbsp;&nbsp;&nbsp;49.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;234<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;may&nbsp; &nbsp;&nbsp;&nbsp;5PA1998 USP&nbsp; &nbsp;&nbsp;&nbsp;37.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;644<br>
    </li>
    <li>216&nbsp; &nbsp;&nbsp;&nbsp;sept&nbsp; &nbsp; 3ZL1998 USP&nbsp; &nbsp;&nbsp;&nbsp;86.00&nbsp; &nbsp;KVM9E&nbsp; &nbsp;234<em onclick="copycode($('code18'));"></em>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
这里返回很多信息，有想要的，也有不想要的。参照模式，返回结果是正确的，因此这里<br>
<div class="blockcode">
<div id="code19">
<ol>
    <li>[sam@chenwy sam]$ grep
    '^[0-9][0-5][0-6]' data.f<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>216&nbsp; &nbsp;&nbsp;&nbsp;sept&nbsp; &nbsp; 3ZL1998 USP&nbsp; &nbsp;&nbsp;&nbsp;86.00&nbsp; &nbsp;KVM9E&nbsp; &nbsp;234</li>
</ol>
</div>
<em onclick="copycode($('code19'));"></em></div>
这样可以返回一个预期的正确结果。<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<strong>以
下要注意有无边界字符的区别 </strong>&nbsp; &nbsp;&nbsp; &nbsp; <br>
<strong>7、模式出现机率</strong><br>
抽取包含数字4至少重复出现两次的所有行，方法如下：<br>
<div class="blockcode">
<div id="code20">
<ol>
    <li>[sam@chenwy sam]$ grep
    '4\{2,\}' data.f<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;may&nbsp; &nbsp;&nbsp;&nbsp;5PA1998 USP&nbsp; &nbsp;&nbsp;&nbsp;37.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;644<em onclick="copycode($('code20'));"></em></li>
</ol>
</div>
</div>
上述语法指明数字4至少重复出现两次，注意有无边
界字符的区别。&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br>
同样，抽取记录使之包含数字9 9 9（三个9），方法如下：<br>
<div class="blockcode">
<div id="code21">
<ol>
    <li>[sam@chenwy sam]$ grep
    '9\{3,\}' data.f<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68</li>
</ol>
</div>
<em onclick="copycode($('code21'));"></em></div>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br>
如果要查询重复出现次数一定的所有行，语法如下，数字9重复出现两次或三次：<br>
<div class="blockcode">
<div id="code22">
<ol>
    <li>[sam@chenwy sam]$ grep
    '9\{3\}' data.f<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>[sam@chenwy sam]$ grep '9\{2\}' data.f<br>
    </li>
    <li>483&nbsp; &nbsp;&nbsp;&nbsp;Sept&nbsp; &nbsp; 5AP1996 USP&nbsp; &nbsp;&nbsp;&nbsp;65.00&nbsp; &nbsp;LVX2C&nbsp; &nbsp;189<br>
    </li>
    <li>47&nbsp; &nbsp;&nbsp; &nbsp;Oct&nbsp; &nbsp;&nbsp;&nbsp;3ZL1998 LPSX&nbsp; &nbsp; 43.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;512<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>484&nbsp; &nbsp;&nbsp;&nbsp;nov&nbsp; &nbsp;&nbsp;&nbsp;7PL1996 CAD&nbsp; &nbsp;&nbsp;&nbsp;49.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;234<em onclick="copycode($('code22'));"></em>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
有时要查询重复出现次数在一定范围内，比如数字或字母重复出现2到6次，下例匹配数字8重复出现2到6次，并以3结尾：<br>
<div class="blockcode">
<div id="code23">
<ol>
    <li>[sam@chenwy sam]$ cat
    myfile<br>
    </li>
    <li>83<br>
    </li>
    <li>888883<br>
    </li>
    <li>8884<br>
    </li>
    <li>88883<br>
    </li>
    <li>[sam@chenwy sam]$ grep '8\{2,6\}3' myfile<br>
    </li>
    <li>888883<br>
    </li>
    <li>88883<em onclick="copycode($('code23'));"></em>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
<strong>8、使用grep匹配&#8220;与&#8221;或者&#8220;或&#8221;模式</strong><br>
g r e p命令加- E参数，这一扩展允许使用扩展模式匹配。例如，要抽取城市代码为2 1 9或2 1 6，方法如下：<br>
<div class="blockcode">
<div id="code24">
<ol>
    <li>[sam@chenwy sam]$ grep
    -E '219|216' data.f<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>216&nbsp; &nbsp;&nbsp;&nbsp;sept&nbsp; &nbsp; 3ZL1998 USP&nbsp; &nbsp;&nbsp;&nbsp;86.00&nbsp; &nbsp;KVM9E&nbsp; &nbsp;234<em onclick="copycode($('code24'));"></em>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br></li>
</ol>
</div>
</div>
<strong>9、空行</strong><br>
结合使用^和$可查询空行。使用- c参数显示总行数：<br>
<div class="blockcode">
<div id="code25">
<ol>
    <li>[sam@chenwy sam]$ grep
    -c '^$' myfile</li>
</ol>
</div>
<em onclick="copycode($('code25'));"></em></div>
使用- n参数显示实际在哪一行：<br>
<div class="blockcode">
<div id="code26">
<ol>
    <li>[sam@chenwy sam]$ grep
    -c '^$' myfile</li>
</ol>
</div>
<em onclick="copycode($('code26'));"></em></div>
<strong>10、匹配特殊字符</strong><br>
查询有特殊含义的字符，诸如$ . ' " * [] ^ | \ + ? ,必须在特定字符前加\。假设要查询包含&#8220;.&#8221;的所有行，脚本如下：<br>
<div class="blockcode">
<div id="code27">
<ol>
    <li>[sam@chenwy sam]$ grep
    '\.' myfile</li>
</ol>
</div>
<em onclick="copycode($('code27'));"></em></div>
或者是一个双引号：<br>
<div class="blockcode">
<div id="code28">
<ol>
    <li>[sam@chenwy sam]$ grep
    '\"' myfile<em onclick="copycode($('code28'));"></em>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br></li>
</ol>
</div>
</div>
以同样的方式，如要查询文件名c o n f t r o l l . c o n f（这是一个配置文件），脚本如下：<br>
<div class="blockcode">
<div id="code29">
<ol>
    <li>[sam@chenwy sam]$ grep
    'conftroll\.conf' myfile<em onclick="copycode($('code29'));"></em>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
    &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br></li>
</ol>
</div>
</div>
<strong>11、查询格式化文件名</strong><br>
使用正则表达式可匹配任意文件名。系统中对文本文件有其标准的命名格式。一般最多六个小写字符，后跟句点，接着是两个大写字符。<br>
<div class="blockcode">
<div id="code30">
<ol>
    <li>[sam@chenwy sam]$ grep
    '^[a-z]\{1,6\}\.[A-Z]\{1,2\}' filename</li>
</ol>
</div>
<em onclick="copycode($('code30'));"></em></div>
这个写法我不知道有没有错 :oops:&nbsp;&nbsp;:oops:&nbsp;&nbsp;:oops: <br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br>
<strong>12 查询IP地址</strong><br>
要查看n n n . n n n网络地址，如果忘了第二部分中的其余部分，只知有两个句点，例如n n n . n n .
.。要抽取其中所有nnn.nnn IP地址，使用[ 0 - 9 ] \ { 3 \ } \ . [ 0 - 0 \ { 3 \ }
\。含义是任意数字出现3次，后跟句点，接着是任意数字出现3次，后跟句点。<br>
<div class="blockcode">
<div id="code31">
<ol>
    <li>[0-9]\{3\}\.[0-9]\{3\}\.'</li>
</ol>
</div>
<em onclick="copycode($('code31'));"></em></div>
<br>
<h2>shell基础八：文本过滤工具（grep）</h2>
<strong>1、类名</strong><br>
<br>
g r e p允许使用国际字符模式匹配或匹配模式的类名形式。<br>
类名及其等价的正则表达式类等价的正则表达式类等价的正则表达式<br>
<br><br>
<div class="msgbody">
<div class="msgheader">QUOTE:</div>
<div class="msgborder">[ [ : u p p e r : ] ] [ A - Z ] [ [ : a l n u m : ] ] [
0 - 9 a - zA-Z]<br>
[ [ : l o w e r : ] ] [ a - z ] [ [ : s p a c e : ] ] 空格或t a b键<br>
[ [ : d i g i t : ] ] [ 0 - 9 ] [ [ : a l p h a : ] ] [ a - z A - Z ]</div>
</div>
<br><br>
<br>
例一：取以5开头，后跟至少两个大写字母：<br>
<div class="blockcode">
<div id="code32">
<ol>
    <li>$grep
    '5[[:upper:]][[:upper]]' data.f</li>
</ol>
</div>
<em onclick="copycode($('code32'));"></em></div>
<br>
取以P或D结尾的所有产品代码：<br>
<div class="blockcode">
<div id="code33">
<ol>
    <li>grep
    '[[:upper:]][[:upper:]][P,D]' data.f</li>
</ol>
</div>
<em onclick="copycode($('code33'));"></em></div>
<strong>2、使用通配符*的匹配模式</strong><br>
<div class="blockcode">
<div id="code34">
<ol>
    <li>$cat testfile<br>
    </li>
    <li>looks<br>
    </li>
    <li>likes<br>
    </li>
    <li>looker<br>
    </li>
    <li>long</li>
</ol>
</div>
<em onclick="copycode($('code34'));"></em></div>
试试如下：<br>
<div class="blockcode">
<div id="code35">
<ol>
    <li>grep "l.*s" testfile</li>
</ol>
</div>
<em onclick="copycode($('code35'));"></em></div>
如在行尾查询某一单词，试如下模式：<br>
<div class="blockcode">
<div id="code36">
<ol>
    <li>grep "ng$" testfile</li>
</ol>
</div>
<em onclick="copycode($('code36'));"></em></div>
这将在所有文件中查询行尾包含单词ng的所有行。<br>
<br>
<strong>3、系统grep</strong><br>
<br>
<strong>文件passwd</strong><br>
<div class="blockcode">
<div id="code37">
<ol>
    <li>[root@Linux_chenwy sam]#
    grep "sam" /etc/passwd<br>
    </li>
    <li>sam:x:506:4::/usr/sam:/bin/bash</li>
</ol>
</div>
<em onclick="copycode($('code37'));"></em></div>
上述脚本查询/ e t c / p a s s w d文件是否包含sam字符串<br>
<br>
如果误输入以下脚本：<br>
<div class="blockcode">
<div id="code38">
<ol>
    <li>[root@Linux_chenwy sam]#
    grep "sam" /etc/password<br>
    </li>
    <li>grep: /etc/password: 没有那个文件或目录</li>
</ol>
</div>
<em onclick="copycode($('code38'));"></em></div>
将返回g r e p命令错误代码'No such file or directory'。<br>
上述结果表明输入文件名不存在，使用g r e p命令- s开关，可屏蔽错误信息。<br>
返回命令提示符，而没有文件不存在的错误提示。<br>
<div class="blockcode">
<div id="code39">
<ol>
    <li>[root@Linux_chenwy sam]#
    grep -s "sam" /etc/password</li>
</ol>
</div>
<em onclick="copycode($('code39'));"></em></div>
如果g r e p命令不支持- s开关，可替代使用以下命令：<br>
<div class="blockcode">
<div id="code40">
<ol>
    <li>[root@Linux_chenwy sam]#
    grep "sam" /tec/password &gt;/dev/null 2&gt;&amp;1</li>
</ol>
</div>
<em onclick="copycode($('code40'));"></em></div>
脚本含义是匹配命令输出或错误（ 2 &gt; $ 1），并将结果输出到系统池。大多数系统管理员称/ d e v / n u l
l为比特池，没关系，可以将之看成一个无底洞，有进没有出，永远也不会填满。<br>
<br>
上述两个例子并不算好，因为这里的目的只想知道查询是否成功。<br>
<br>
如要保存g r e p命令的查询结果，可将命令输出重定向到一个文件。<br>
<div class="blockcode">
<div id="code41">
<ol>
    <li>[root@Linux_chenwy sam]#
    grep "sam" /etc/passwd &gt;/usr/sam/passwd.out<br>
    </li>
    <li>[root@Linux_chenwy sam]# cat /usr/sam/passwd.out<br>
    </li>
    <li>sam:x:506:4::/usr/sam:/bin/bash</li>
</ol>
</div>
<em onclick="copycode($('code41'));"></em></div>
脚本将输出重定向到目录/ t m p下文件p a s s w d . o u t中。<br>
<br>
<strong>使用ps命令</strong><br>
使用带有ps x命令的g r e p可查询系统上运行的进程。ps x命令意为显示系统上运行的所有进程列表。要查看D N
S服务器是否正在运行（通常称为n a m e d），方法如下：<br>
<div class="blockcode">
<div id="code42">
<ol>
    <li>[root@Linux_chenwy sam]#
    ps ax|grep "named"<br>
    </li>
    <li> 2897 pts/1&nbsp; &nbsp; S&nbsp; &nbsp;&nbsp; &nbsp;0:00 grep named</li>
</ol>
</div>
<em onclick="copycode($('code42'));"></em></div>
输出也应包含此g r e p命令，因为g r e p命令创建了相应进程， ps x将找到它。在g r e p命令中使用- v选项可丢弃p
s命令中的g r e p进程。如果ps x不适用于用户系统，替代使用ps -ef。这里，由于我没有DNS服务，因而只有grep进程。<br>
<br>
<strong>对一个字符串使用grep</strong><br>
g r e p不只应用于文件，也可应用于字符串。为此使用e c h o字符串命令，然后对g r e p命令使用管道输入。<br>
<div class="blockcode">
<div id="code43">
<ol>
    <li>[root@Linux_chenwy sam]#
    STR="Mary Joe Peter Pauline"<br>
    </li>
    <li>[root@Linux_chenwy sam]# echo $STR | grep "Mary"<br>
    </li>
    <li>Mary Joe Peter Pauline</li>
</ol>
</div>
<em onclick="copycode($('code43'));"></em></div>
匹配成功实现。<br>
<br>
<div class="blockcode">
<div id="code44">
<ol>
    <li>[root@Linux_chenwy sam]#
    echo $STR | grep "Simon"</li>
</ol>
</div>
<em onclick="copycode($('code44'));"></em></div>
因为没有匹配字符串，所以没有输出结果。<br>
<br>
<strong>4、egrep</strong><br>
e g r e p代表e x p r e s s i o n或extended grep，适情况而定。e g r e p接受所有的正则表达式， e
g r e p的一个显著特性是可以以一个文件作为保存的字符串，然后将之传给e g r e p作为参数，为此使用- f开关。如果创建一个名为g r
e p s t r i n g s的文件，并输入4 8 4和4 7：<br>
<div class="blockcode">
<div id="code45">
<ol>
    <li>[root@Linux_chenwy sam]#
    vi grepstrings<br>
    </li>
    <li>[root@Linux_chenwy sam]# cat grepstrings<br>
    </li>
    <li>484<br>
    </li>
    <li>47</li>
</ol>
</div>
<em onclick="copycode($('code45'));"></em></div>
<br>
<div class="blockcode">
<div id="code46">
<ol>
    <li>[root@Linux_chenwy sam]#
    egrep -f grepstrings data.f<br>
    </li>
    <li>47&nbsp; &nbsp;&nbsp; &nbsp;Oct&nbsp; &nbsp;&nbsp;&nbsp;3ZL1998 LPSX&nbsp; &nbsp; 43.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;512<br>
    </li>
    <li>484&nbsp; &nbsp;&nbsp;&nbsp;nov&nbsp; &nbsp;&nbsp;&nbsp;7PL1996 CAD&nbsp; &nbsp;&nbsp;&nbsp;49.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;234</li>
</ol>
</div>
<em onclick="copycode($('code46'));"></em></div>
上述脚本匹配d a t a . f中包含4 8 4或4 7的所有记录。当匹配大量模式时， -
f开关很有用，而在一个命令行中敲入这些模式显然极为繁琐。<br>
<br>
如果要查询存储代码3 2 L或2 C C，可以使用（|）符号，意即&#8220;|&#8221;符号两边之一或全部。<br>
<div class="blockcode">
<div id="code47">
<ol>
    <li>[root@Linux_chenwy sam]#
    egrep '(3ZL|2CC)' data.f<br>
    </li>
    <li>47&nbsp; &nbsp;&nbsp; &nbsp;Oct&nbsp; &nbsp;&nbsp;&nbsp;3ZL1998 LPSX&nbsp; &nbsp; 43.00&nbsp; &nbsp;KVM9D&nbsp; &nbsp;512<br>
    </li>
    <li>219&nbsp; &nbsp;&nbsp;&nbsp;dec&nbsp; &nbsp;&nbsp;&nbsp;2CC1999 CAD&nbsp; &nbsp;&nbsp;&nbsp;23.00&nbsp; &nbsp;PLV2C&nbsp; &nbsp;68<br>
    </li>
    <li>216&nbsp; &nbsp;&nbsp;&nbsp;sept&nbsp; &nbsp; 3ZL1998 USP&nbsp; &nbsp;&nbsp;&nbsp;86.00&nbsp; &nbsp;KVM9E&nbsp; &nbsp;234</li>
</ol>
</div>
<em onclick="copycode($('code47'));"></em></div>
可以使用任意多竖线符&#8220; |&#8221;，例如要查看在系统中是否有帐号l o u i s e、m a t t y或pauline ，使用w h
o命令并管道输出至e g r e p。<br>
<div class="blockcode">
<div id="code48">
<ol>
    <li>$who |egrep
    (louise|matty|pauline)</li>
</ol>
</div>
<em onclick="copycode($('code48'));"></em></div>
还可以使用^符号排除字符串。如果要查看系统上的用户，但不包括m a t t y和p a u l i n e，方法如下：<br>
<div class="blockcode">
<div id="code49">
<ol>
    <li>$who |egrep -v
    '^(matty|pauline)'</li>
</ol>
</div>
<em onclick="copycode($('code49'));"></em></div>
如果要查询一个文件列表，包括s h u t d o w n、s h u t d o w n s、r e b o o t和r e b o o t
s，使用e g r e p可容易地实现。<br>
<div class="blockcode">
<div id="code50">
<ol>
    <li>$egrep '(shutdown
    |reboot) (s)?' *</li>
</ol>
</div>
<em onclick="copycode($('code50'));"></em></div>
<br>from：<br><a  href="http://bbs.chinaunix.net/thread-446683-1-1.html">http://bbs.chinaunix.net/thread-446683-1-1.html</a><br><img src ="http://www.cppblog.com/beautykingdom/aggbug/116859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-06-01 09:48 <a href="http://www.cppblog.com/beautykingdom/archive/2010/06/01/116859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>史上最强bash函数库</title><link>http://www.cppblog.com/beautykingdom/archive/2010/05/03/114291.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 03 May 2010 14:42:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/05/03/114291.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/114291.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/05/03/114291.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/114291.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/114291.html</trackback:ping><description><![CDATA[<pre>## ---------------------------------------------------------<br>## common functions<br>## author:   samli AT tencent.com | huanlf AT gmail.com<br>## usage:    source "./func-common.sh"<br>## last mod: 2009-07-10<br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## ---------------- classical usage ------------------------<br>## export WORKDIR=$( cd ` dirname $0 ` &amp;&amp; pwd )<br>## <br>## if [[ ! -r "$WORKDIR/func-common.sh" ]]; then<br>##     echo "[$WORKDIR/func-common.sh] NOT FOUND"<br>##     exit 1<br>## fi<br>## <br>## . "$WORKDIR/func-common.sh" || exit 1<br>## <br>## cd "$WORKDIR" || exit 1<br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## set -x <br>## set -e     ## Sorry, can not set -e here, fix later<br><br>## -------------------- GLOBAL VAR -------------------------<br><br>## some vars initialized in the end of this file, check it<br><br>## make sure we will find commands needed<br>export PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:$PATH<br><br>## just a var to keep the val from get_localip<br>## use a strange var name to avoid collision<br>export LLLOCALIP<br><br>## the dir we are working in<br>export WORKDIR<br><br>## some addictional logs may redirected to here<br>## such as: make &gt;&gt; $LLLOG &amp;&amp; make install &gt;&gt; $LLLOG<br>## use a strange var name to avoid collision<br>export LLLOG<br>export LLLOGDIR<br><br>## set locale as POSIX, to work around with i180-ed apps<br>export LANG=C<br>export LC_ALL=C<br><br>## set umask to 022 to avoid wrong access mode<br>umask 022<br><br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## -------------------- colourful print --------------------<br><br>## ANSI Foreground color codes:<br>## 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white 39=default<br>## ANSI Background color codes:<br>## 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white 49=default<br><br>COLOR_RED=$(    echo -e "\e[31;49m" ) <br>COLOR_GREEN=$(  echo -e "\e[32;49m" )<br>COLOR_YELLO=$(  echo -e "\e[33;49m" )<br>COLOR_BLUE=$(   echo -e "\e[34;49m" )<br>COLOR_MAGENTA=$(echo -e "\e[35;49m" )<br>COLOR_CYAN=$(   echo -e "\e[36;49m" )<br>COLOR_RESET=$(  echo -e "\e[0m"     )<br><br>## *msg argv: "$str"<br>msg()  { gmsg "$@";                               }<br>rmsg() { echo "${COLOR_RED}$*${COLOR_RESET}";     }<br>gmsg() { echo "${COLOR_GREEN}$*${COLOR_RESET}";   }<br>ymsg() { echo "${COLOR_YELLO}$*${COLOR_RESET}";   }<br>bmsg() { echo "${COLOR_BLUE}$*${COLOR_RESET}";    }<br>mmsg() { echo "${COLOR_MAGENTA}$*${COLOR_RESET}"; }<br>cmsg() { echo "${COLOR_CYAN}$*${COLOR_RESET}";    }<br><br># colourful print without "\n"<br>msg_()  {  msg "$@" | tr -d '\n'; }<br>rmsg_() { rmsg "$@" | tr -d '\n'; }<br>gmsg_() { gmsg "$@" | tr -d '\n'; }<br>ymsg_() { ymsg "$@" | tr -d '\n'; }<br>bmsg_() { bmsg "$@" | tr -d '\n'; }<br>mmsg_() { mmsg "$@" | tr -d '\n'; }<br>cmsg_() { cmsg "$@" | tr -d '\n'; }<br><br>## normal message print and log<br>logmsg()<br>{<br>    local t=$( date '+%F %T' )<br><br>    gmsg "[$t $LLLOCALIP]: $*"<br><br>    ## no color in logs<br>    mkdir -p "$LLLOGDIR" || { rmsg "can not create $LLLOGDIR"; exit 1; }<br>    echo "[$t $ip]: $*" &gt;&gt; "$LLLOG"<br>}<br><br>## normal message print and log, without "\n"<br>logmsg_()<br>{<br>    local t=$( date '+%F %T' )<br><br>    gmsg_ "[$t $LLLOCALIP]: $*"<br><br>    ## no color in logs<br>    mkdir -p "$LLLOGDIR" || { rmsg "can not create $LLLOGDIR"; exit 1; }<br>    echo -n "[$t $ip]: $*" &gt;&gt; "$LLLOG"<br>}<br><br>## warning<br>warn()<br>{<br>    local t=$( date '+%F %T' )<br><br>    ## write to STDERR<br>    mmsg "[$t $LLLOCALIP]WARNING: $*" &gt;&amp;2<br><br>    mkdir -p "$LLLOGDIR" || { rmsg "can not create $LLLOGDIR"; exit 1; }<br>    echo "[$t $ip]WARNING: $*" &gt;&gt; "$LLLOG"<br>}<br><br>## fatal, will exit with code 1<br>die()<br>{<br>    local t=$( date '+%F %T' )<br><br>    ## write to STDERR<br>    rmsg "[$t $LLLOCALIP]FATAL: $*" &gt;&amp;2<br><br>    mkdir -p "$WORKDIR/log.d" || { rmsg "can not create $WORKDIR/log.d"; exit 1; }<br>    echo "[$t $ip]FATAL: $*" &gt;&gt; "$LLLOG"<br><br>    exit 1<br>}<br><br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## ---------------------- IP / NIC  ------------------------<br><br>## get all interfaces ip addr, but default lo<br>get_ipaddr()<br>{<br>    local ipall=$(<br>        /sbin/ifconfig | <br>          awk '/inet addr:/ { if ($2 !~ /127.0.0.1/) { print substr($2,6)} } '<br>    )<br><br>    ipall=$( echo $ipall )  ## trim spaces, blank charachers<br>    <br>    if [[ -n $ipall ]]; then<br>        echo $ipall<br>    else<br>        return 1<br>    fi<br>}<br><br>## get all lan ipaddr. not strict<br>get_localip_all()<br>{<br>    local ip ipall<br><br>    for ip in $( get_ipaddr ); do<br>       case $ip in<br>           172.*|192.*|10.*)<br>               ## should deal with the newline symbol '\n' by yourself<br>               ipall="$ipall $ip"<br>               ;;<br>       esac<br>    done<br><br>    ipall=$( echo $ipall )  ## trim spaces, blank charachers<br><br>    if [[ -n $ipall ]]; then<br>        echo $ipall<br>    else<br>        return 1<br>    fi<br>}<br><br>## get login ip from ssh env val, useful if we have mutilple NICs<br>## this func is not very reliable, use get_localip instead<br>get_loginip()<br>{<br>    local ip<br><br>    for ip in $( echo $SSH2_CLIENT    | awk '{ print $3 }' ) \<br>              $( echo $SSH_CONNECTION | awk '{ print $3 }' ) \<br>              $( echo $SSH_CLIENT     | awk '{ print $1 }' ) ; do<br>        if [[ -n $ip ]]; then  ## never failed ?<br>            echo $ip<br>            return 0<br>        fi<br>    done<br><br>    return 1<br>}<br><br>## get a lan ipaddr, must be an private IP, the ip we login is prefered<br>get_localip()<br>{<br>    ## to speed up, this func may be called frequently<br>    ## maybe we should use $LLLOCALIP directlly instead of callin get_localip<br>    [[ -n "$LLLOCALIP" ]] &amp;&amp; { echo $LLLOCALIP;  return 0; }<br><br>    local default_ip=127.0.0.1  ## make sure we return an "IP"<br>    local ipall=$( get_localip_all )<br>    local ip<br><br>    for ip in $( get_loginip ) $ipall; do<br>       case $ip in      ## check if a private IP, need more strict checking ?<br>           172.*|192.*|10.*)<br>                # make sure we find the ip on local host<br>                # result from get_login may not correct<br>                # note that we do not get '127.0.0.1' from get_localip_all<br>                if echo $ipall | grep -wq $ip; then<br>                    LLLOCALIP=$ip <br>                    break<br>                fi<br>            ;;<br>        esac<br>    done<br><br>    if [[ -n "$LLLOCALIP" ]]; then<br>        echo $LLLOCALIP<br>        return 0<br>    else<br>        echo $default_ip<br>        return 1<br>    fi<br>}<br><br>## return the the ip on the given interface<br>## argv: $interface<br>## example: get_ip_for_interface "eth0"<br>get_ip_for_interface()<br>{<br>    local iface=$1<br><br>    ## /sbin/ifconfig "$iface" 2&gt;/dev/null |<br>    /sbin/ifconfig "$iface" |<br>       awk '/inet addr:/ { print substr($2,6) } '<br><br>    # return the status of ifconfig<br>    return ${PIPESTATUS[0]}<br>}<br><br>## include sub interface's ip<br>get_all_ip_for_interface()<br>{<br>    local iface=$1<br>    local ipall=$( <br>        {   <br>            ## physical interface<br>            /sbin/ifconfig | grep -A1 -E "^$iface[[:space:]]+"<br>            ## sub interface, such as eth0:0<br>            /sbin/ifconfig | grep -A1 -E "^$iface:[0-9]+[[:space:]]+"<br>        } |<br>        awk '/inet addr:/ { print substr($2,6) } '<br>    )<br><br>    ipall=$( echo $ipall )  ## trim spaces, blank charachers<br><br>    if [[ -n $ipall ]]; then<br>        echo $ipall<br>    else<br>        return 1<br>    fi<br>}<br><br><br>## return the netmask for an interface<br>## argv: $interface<br>## example: get_netmask_for_interface "eth0"<br>get_netmask_for_interface()<br>{<br>    local iface=$1<br>    [[ -n $iface ]] || return 1<br><br>    /sbin/ifconfig "$iface" | awk -F: '/Mask:/ { print $NF }'<br><br>    ## return the status of ifconfig<br>    return ${PIPESTATUS[0]}<br>}<br><br>## 2009-01-12, get mtu for an interface<br>## argv: $interface<br>## example: get_mtu_for_interface "eth0"<br>get_mtu_for_interface()<br>{<br>    local iface=$1<br>    ## mtu on the sub ifc is the same with the physical ifc<br>    ## local iface=${1%%:*}<br><br>    /sbin/ifconfig "$iface" | <br>      awk '/MTU:/ {<br>      if ( $3 ~ /RUNNING/ ) {<br>          print substr($5,5)<br>      }<br>      else {<br>          print substr($4,5)<br>      }  }'<br><br>    ## return the status of ifconfig<br>    return ${PIPESTATUS[0]}<br>}<br><br>## return the interface name having the "$ip"<br>## maybe a sub interface or a real physical interface<br>get_interface_by_ip()<br>{<br>    local ip=$1<br>    local ifc<br><br>    ifc=$(<br>        ## use -a to prevent that the iface is down by ip not cleared<br>        /sbin/ifconfig -a | grep -B1 -w "$ip" |<br>        awk ' NR == 1 { print $1 } ' <br>    )<br><br>    if [[ -n $ifc ]]; then<br>        echo $ifc<br>    else<br>        return 1<br>    fi<br>}<br><br>## return a real physical interface even if the ip is on a sub interface<br>get_real_interface_by_ip()<br>{<br>    local ip=$1<br>    local r_ifc<br><br>    r_ifc=$( get_interface_by_ip "$ip" | sed 's/:[0-9]\+//' )<br><br>    if [[ -n $r_ifc ]]; then<br>        echo $r_ifc<br>    else<br>        return 1<br>    fi<br>}<br><br>## return the interface with local ip<br>get_local_iface()<br>{<br>    local ip<br>    local ifcall=$( <br>        for ip in $( get_localip_all ); do<br>            get_interface_by_ip "$ip"<br>        done<br>    )<br><br>    if [[ -n $ifcall ]]; then<br>        echo $ifcall<br>    else<br>        return 1<br>    fi<br>}<br><br>## return the interface with wan ip, actually, with not lan ip<br>get_wan_iface()<br>{<br>    local wanall<br>    ## one interface per line<br>    get_local_iface | xargs -n1 &gt; /tmp/local.iface<br>    /sbin/ifconfig | grep -B1 'addr:[0-9]' |<br>      awk '/^(eth|wlan|ppp)/ { print $1 }' &gt; /tmp/all.iface<br><br>    wanall=$( grep -xvf /tmp/local.iface /tmp/all.iface )<br>    ## /bin/rm "/tmp/local.iface" "/tmp/all.iface"<br><br>    if [[ -n $wanall ]]; then<br>        echo $wanall<br>    else<br>        return 1<br>    fi<br>}<br><br>## return physical iface with local ip<br>get_real_local_iface()<br>{<br>    get_local_iface | xargs -n1 | sed 's/:.*//' | sort -u<br>}<br><br>## return physical iface with wan ip<br>get_real_wan_iface()<br>{<br>    get_wan_iface   | xargs -n1 | sed 's/:.*//' | sort -u<br>}<br><br>## return the interface without a ip configured on it<br>get_free_iface()<br>{<br>    local ifcall=$(<br>        /sbin/ifconfig -a |<br>          grep -w 'BROADCAST' -B1 |<br>          awk '/^[a-z\.]+/ { print $1 }'<br>    )<br><br>    if [[ -n $ifcall ]]; then<br>        echo $ifcall<br>    else<br>        return 1<br>    fi<br>}<br><br>## if we have eth0, this fun may return eth0:0<br>## if we have eth:0, may return eth0:1 ....<br>get_a_free_subname_on()<br>{<br>    local iface=$1<br>    local i=0<br>    local ip=<br>    <br>    while (( i &lt; 100 )); do<br>        ip=$( get_ip_for_interface "${iface}:$i" )<br>        if [[ -z $ip ]]; then   ## no ip, so it's free<br>            echo "${iface}:$i"<br>            return 0    ## return directly, not use break<br>        fi<br>        <br>        (( i++ ))<br>    done<br>        <br>    return 1<br>}<br><br>## check if we have at least a sub interface, may used on lvs box<br>## return true / false<br>has_sub_iface()<br>{<br>    /sbin/ifconfig | grep -m1 -Eq '^eth[0-9]+:[0-9]+'<br>}<br><br>## call this fun two times, the increment is the flux<br>## argv: $interface<br>get_current_transmit_flux_for()<br>{<br>    local dev=$1<br>    local NETDEV="/proc/net/dev"<br><br>    grep -w "$dev" "$NETDEV" | awk -F: '{ print $2; }' | awk '{ print $9; }'<br><br>    return ${PIPESTATUS[0]}<br>}<br><br>## try to find default gw, return the most used ip if default gw not found<br>## this func check gw ip loosely, check following code<br>get_gateway_ip()<br>{<br>    /bin/netstat -nr | perl -lnwe '<br>        ( $dest, $gw ) = (split)[0,1];<br>        if ( $dest eq "0.0.0.0" ) {<br>            $default_gw = $gw;<br>        }<br>        else {  <br>            $rec{ $gw }++; <br>        }<br><br>        END {<br>        if ( defined $default_gw ) {<br>            print $default_gw;<br>            exit 0;<br>        }<br>    <br>        $max = 0;<br>        for $g ( keys %rec ) {<br>            if ( $rec{ $g } &gt; $max ) {<br>                $max = $rec{ $g };<br>                $default_gw = $g;<br>            }<br>        }<br>        print "$default_gw";<br>    }'<br>}<br><br>## this func check DEFAULT gw ip, may return more than one ip !<br>get_default_gateway_ip_on_interface()<br>{<br>    local iface=$1<br><br>    /bin/netstat -nr |<br>    awk -vifc="$iface" '{ if ($1 == "0.0.0.0" &amp;&amp; $NF == ifc) { print $2 } }'  <br>}<br><br>## may return more than 1 ip, check it by yourself !<br>## this func check gwip loosely, check following code<br>get_gateway_ip_on_interface()<br>{   <br>    local ifc=$1<br><br>    if [[ -z $ifc ]]; then<br>        return 1<br>    fi<br><br>    netstat -nr | perl -lne '<br>        BEGIN{ $ifc = pop @ARGV; }<br><br>        next unless /^\d/;<br><br>        if (/^0\.0\.0\.0\s+(\d+\.\d+\.\d+\.\d+).*$ifc\s*$/) {<br>            $found=1;<br>            print $1;<br>            exit 0;<br>        }<br>        elsif (/^\d+\.\d+\.\d+\.\d+\s+(\d+\.\d+\.\d+\.\d+).*$ifc\s*$/) {<br>            next if $1 eq "0.0.0.0";<br>            $gw{$1}++;<br><br>            ## print "found [$_]"<br>        }<br><br>        END {<br>            unless ( $found ) {<br>                for ( sort keys %gw ) {<br>                    ## print "$_\t$gw{$_}";<br>                    print $_;<br>                }<br>            }<br>        }<br><br>    ' "$ifc"<br>}<br><br>## check if a host online<br>## return true / false<br>is_host_online()<br>{<br>    local host=$1<br>    local try=2<br><br>    [[ -n $host ]] || return 1<br><br>    ## some old versions of nmap seems more slowly when dest unreachable<br>    while (( try &gt;= 0 )); do<br>        if ping -c2 -w2 "$host" 2&gt;/dev/null | grep -q ' [12] received'; then<br>            return 0<br>        fi<br><br>        (( try-- ))<br>    done<br><br>    return 1<br>}<br><br>## return true / false<br>is_a_valid_port()<br>{<br>    local port=$1<br>    local p=$( echo $port | tr -d '0-9' )<br><br>    ## having non-digit character<br>    if [[ -n "$p" ]]; then<br>        return 1<br>    fi<br>    <br>    if (( port &gt;= 1 )) &amp;&amp; (( port &lt;= 65535 )); then<br>        return 0<br>    else<br>        return 1<br>    fi<br>}<br><br>## return true / false<br>is_an_valid_ip()<br>{<br>    local ip=$1<br><br>    ## simple checking<br>    if [[ "$ip" == "0.0.0.0" ]] || [[ "$ip" == "255.255.255.255" ]]; then<br>        return 1<br>    fi<br><br>    ## not perfect checking ...<br>    echo "$ip" | grep -qE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'<br>}<br><br>ifdown_an_ip()<br>{<br>    local ip=$1<br>    <br>    [[ -n $ip ]] || return 1<br><br>    local iface=$( get_interface_by_ip "$ip" )<br>    if [[ -z $iface ]]; then<br>        return 1    ## no-op<br>    fi<br><br>    ifdown_an_iface "$iface"<br>}<br><br>## dangerous to down a phycal interface, use "force" as argv[2] if you know what you are doing<br>ifdown_an_iface()<br>{<br>    local iface=$1<br>    local downall=$2<br><br>    local ip_cnt<br><br>    [[ -n $iface ]] || return 1<br><br>    case $iface in<br>    *:[0-9]*)   ## sub interface, just clear the ip configured<br>        /sbin/ifconfig "$iface" 0 &amp;&gt; /dev/null || :<br>        ;;<br>    *)  ## physical interface, if there is only one ip, down the nic<br>        ## else just clear the ip configured<br>        ip_cnt=$( get_all_ip_for_interface "$iface" | xargs -n1 | wc -l )<br>        if (( ip_cnt &gt; 1 )); then<br>            if [[ $downall == "force" ]]; then<br>                /sbin/ifconfig "$iface" 0 down &amp;&gt; /dev/null || :<br>            else<br>                /sbin/ifconfig "$iface" 0      &amp;&gt; /dev/null || :<br>            fi<br>        ## no mare than 1 ip on it, safe<br>        else<br>            /sbin/ifconfig "$iface" 0 down     &amp;&gt; /dev/null || :<br>        fi<br>        ;;<br>    esac<br><br>    if [[ -z $( get_ip_for_interface "$iface" ) ]]; then<br>        return 0<br>    else<br>        return 1<br>    fi<br>}<br><br>use_ip_2ping()<br>{<br>    local src_ip=$1<br>    local dest_ip=$2<br><br>    local cnt=3<br><br>    while (( cnt &gt;= 0 )); do<br>        ping -c1 -w1 -I "$src_ip" "$dest_ip" 2&gt;/dev/null | <br>         grep -q '[[:blank:]]0% packet loss'<br><br>        (( $? == 0 )) &amp;&amp; return 0<br>        (( cnt-- ))<br>    done<br><br>    return 1<br>}<br><br>## ---------------------------------------------------------<br><br><br><br><br><br>## ------------------- dir /path / --------------------------<br><br>## get the working dir name, may return the dirname of the script we are running<br>## actually, we may have to find the workdir first to source this file -_-!<br>## anyway, var LLLOG needs this<br>get_workdir()<br>{<br>    local d<br><br>    ## may be I should check $0 ~ *.sh simplly<br>    case $- in<br>        *i*)    ## sourced in an interactive-bash ?<br>            d=$( pwd )<br>            ;;<br>        *)<br>            d=$( cd `dirname "$0"` &amp;&amp; pwd )<br>            ;;<br>    esac<br><br>    echo "$d"<br>}<br><br>## rename a file or dir to make sure the filename or dirname would be OK to reuse<br>## if "abc" exits, it will be renamed as "abc.old"<br>## argv: $pathname<br>## example: remove_old "/usr/local/apache" &amp;&amp; ./configure --prefix=/usr/local/apache<br>remove_old()<br>{<br>    local name="$1"<br>    local oldname="${name}.old"<br><br>    if ! [[ -e "$name" || -L "$name" ]]; then<br>        return<br>    fi<br>    <br>    ## never rename '/', $1 must be an error argv<br>    [[ "$name" == "/" ]] &amp;&amp; die "you really rename / ?"<br><br>    [[ -e "$oldname"  ]] &amp;&amp; rm -rf "$oldname"<br>    [[ -L "$oldname"  ]] &amp;&amp; rm -rf "$oldname"<br><br>    /bin/mv "$name" "$oldname"<br>}<br><br>## a simple mktemp. some old os have no /bin/mktemp, to create uniq temp file/dir<br>## the command on slk and suse behaves differently, so re-write it<br>## argv1: -d / -f<br>## argv2: $path<br>## example: mktemp -f /tmp/<br>mktemp()<br>{<br>    local opt=$1        ## file or dir<br>    local dir=$2        ## base path<br>    local tmp<br><br>    ## make sure we find a uniq file / dir name<br>    while :; do<br>        if [[ -n "$dir" ]]; then<br>            tmp="$dir/$( date +%s ).$$.$RANDOM"<br>        elif [[ -n "$WORKDIR" ]]; then<br>            tmp="$WORKDIR/$( date +%s ).$$.$RANDOM"<br>        else<br>            tmp="./$$.$RANDOM.$( date +%s )"<br>        fi<br><br>        [[ -e $tmp ]] || break<br>    done<br><br>    if [[ $opt == "-d" ]]; then<br>        mkdir -p "$tmp" || return 1<br>    else<br>        mkdir -p "$( dirname $tmp )" || return 1<br>        touch "$tmp"    || return 1<br>    fi<br><br>    echo $tmp<br>}<br><br>## essential files/dirs must be there<br>## argv: $pathname<br>## example: must_exist "$WORKDIR/mysql.tar.bz"<br>must_exist()<br>{<br>    local t<br>    local flag=0<br><br>    for t; do<br>        if [[ -e "$t" ]]; then<br>            logmsg "[$t] FOUND, OK"<br>        else<br>            flag=1<br>            warn "[$t] NOT FOUND, NOTOK"<br>        fi<br>    done<br><br>    (( flag != 0 )) &amp;&amp; die "FILES NOT FOUND, ABORTING ..."<br>}<br><br>## try to find the mountpoint for a pathname<br>get_mountpoint_for_pathname()<br>{<br>    local path=$1<br>    <br>    [[ -n $path ]] || return 1<br>    [[ -e $path ]] || return 1<br><br>    df "$path" 2&gt;/dev/null | awk 'NR == 2 { print $NF }'<br>}<br><br>## try to find the mountpoint for a pathname<br>get_devname_for_mountpoint()<br>{<br>    local path=$1<br><br>    [[ -n $path ]] || return 1<br>    [[ -d $path ]] || return 1<br><br>    df "$path" 2&gt;/dev/null | awk 'NR == 2 { print $1 }'<br>}<br><br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## --------------------- OS / HW info ----------------------<br><br>## check if running on SUSE OS<br>## return true / false<br>check_suseos()<br>{<br>    if [[ -f "/etc/SuSE-release" ]]; then<br>        grep -wqF 'SUSE' /etc/SuSE-release &amp;&amp; return 0<br>    fi<br><br>    [[ -x /sbin/yast2 ]]  &amp;&amp; return 0 || :<br>    <br>    return 1<br>}<br><br>## check if running on Slackware OS<br>## return true / false<br>check_slkos()<br>{<br>    if [[ -f "/etc/slackware-version" ]]; then<br>        grep -wqF 'Slackware' /etc/slackware-version &amp;&gt;/dev/null &amp;&amp; return 0<br>    fi<br><br>    [[ -x /sbin/installpkg ]]  &amp;&amp; return 0 || :<br><br>    return 1<br>}<br><br>## check if running on RedHat OS<br>## return true / false<br>check_rhos()<br>{<br>    if [[ -f /etc/redhat-release ]]; then<br>        grep -wqi red /etc/redhat-release &amp;&gt;/dev/null &amp;&amp; return 0<br>    fi<br><br>    return 1<br>}<br><br>## print OS info, now just os version <br>get_osinfo()<br>{<br>    ## use xargs to delete '\n', I love xargs!<br>    if check_suseos; then<br>        xargs &lt; /etc/SuSE-release<br>    elif check_slkos; then<br>        xargs &lt; /etc/slackware-version<br>    elif check_rhos; then<br>        xargs &lt; /etc/redhat-release<br>    else<br>        ## lsb_release may be found on ubuntu, debian, etc.<br>        lsb_release -d 2&gt;/dev/null || echo 'UNKNOWD OS'<br>    fi<br>}<br><br>## print OS name<br>get_osname()<br>{<br>    if check_suseos; then<br>        echo SUSE<br>    elif check_slkos; then<br>        echo SLK<br>    elif check_rhos; then<br>        echo RH<br>    else<br>        echo UNKNOWN<br>        return 1<br>    fi<br>}<br><br>## with bit flag<br>get_osname2()<br>{<br>    echo $( get_osver )_$( get_cputype )<br>}<br><br>## return 32/64, based on OS but not hardware<br>get_cputype()<br>{<br>    if uname -a | grep -Fq 'x86_64'; then<br>        echo 64<br>    else<br>        echo 32<br>    fi<br>}<br><br>get_osver()<br>{<br>    if grep -Eq 'Slackware[[:blank:]]+8\.[0-9]'  /etc/slackware-version; then<br>        echo slk8<br>    elif grep -Eq 'Slackware[[:blank:]]+10\.[0-9]'  /etc/slackware-version; then<br>        echo slk10<br>    elif check_suseos; then<br>        echo "suse$( get_cputype )"<br>    elif check_rhos; then<br>        echo "rh$( get_cputype   )"<br>    else<br>        echo "UNKNOWN"<br>    fi 2&gt;/dev/null<br>}<br><br>## return kernel version: 2.4 / 2.6<br>get_kernver()<br>{<br>    /sbin/kernelversion 2&gt;/dev/null ||<br>        uname -r | grep -o '^2\..'<br>}<br><br>## get free capacity of a partition by a filename/pathname<br>get_free_cap()<br>{<br>    local path=$1<br><br>    if [[ ! -e "$path" ]]; then<br>        echo 0B<br>        return<br>    fi<br><br>    ## df so cool!<br>    df -h "$path" | awk 'NR==2 { print $4 }'<br>}<br><br><br>## get the size of files by du<br>## example: get_file_size "/var/log"<br>get_file_size()<br>{<br>    ## do not quote [$file], may contain more than one filename<br>    local file=$1<br>    local size=$( du -sh $file 2&gt;/dev/null | awk '{ print $1; exit }' || echo 0B )<br><br>    echo ${size: -1} | grep -q '^[0-9]$' &amp;&amp; size=${size}B<br>    echo ${size:-0B}<br>}<br><br>## get the size of physical mem<br>get_mem_size()<br>{<br>    local unit=$1<br>    local resut dividend<br><br>    case $unit in <br>    k|K)<br>        dividend=1<br>        ;;<br>    m|M)<br>        dividend=1000<br>        ;;<br>    g|G)<br>        dividend=1000000<br>        ;;<br>    t|T)<br>        dividend=1000000000<br>        ;;<br>    *)<br>        dividend=1  ## default, K<br>        ;;<br>    esac<br><br>    resut=$( awk '/^MemTotal/ { print $2 }' /proc/meminfo )<br>    calculate2 "$resut / $dividend"<br>}<br><br>## get the size of all hard disks<br>get_hdd_size()<br>{<br>    local unit=$1<br>    local resut dividend<br><br>    case $unit in <br>    k|K)<br>        dividend=1<br>        ;;<br>    m|M)<br>        dividend=1000<br>        ;;<br>    g|G)<br>        dividend=1000000<br>        ;;<br>    t|T)<br>        dividend=1000000000<br>        ;;<br>    *)<br>        dividend=1  ## default, K<br>        ;;<br>    esac<br><br>    ## check /proc/partitions, fdisk -l not reliable<br>    resut=$( <br>        awk 'BEGIN{ total = 0 }<br>        {<br>            if ( $1 !~ /^[[:space:]]*[0-9]+/ ) {<br>                next<br>            }<br>        <br>            if ( $NF ~ /cciss\/c[0-9]d[0-9][[:space:]]*$/ || $NF ~ /[sh]d[a-z][[:space:]]*$/ ) {<br>                total += $3<br>            }<br>        }<br>        END { printf("%d", total) }' /proc/partitions<br>    )<br><br>    calculate2 "$resut / $dividend"<br>}<br><br>## get cpu name: intel/amd x $core_num<br>get_cpu_name()<br>{<br>    awk 'BEGIN{ num = 0; name = "unknow"; FS = ":" }<br>    {<br>        if ( $1 !~ /^model name/ ) {<br>            next<br>        }<br>        if ( $0 ~ /[Ii]ntel/ ) {<br>            name = "Intel"<br>        }<br>        else if ( $0 ~ /AMD/ ) {<br>            name = "Amd"<br>        }<br>        else {<br>            name = 'unknow'<br>        }<br>        num++<br>    }<br>    END { print name"x"num }' /proc/cpuinfo<br>}<br><br>## get cpu cache sizes<br>get_cpu_cachesize()<br>{<br>    awk 'BEGIN{ num = 0; size = 0; FS = ":"; }<br>    {<br>        if ( $1 ~ /^cache size/ ) {<br>            num++<br>            size = $2 + 0<br>        }<br>    }<br>    END { print size"Kx"num }' /proc/cpuinfo<br>}<br><br>## 2009-01-14 samli, check if a partition readonly<br>## argv: $mountpoint / $pathname<br>## return true / false<br>is_partition_readonly()<br>{<br>    local p=$1<br>    local mountpoint<br>    local rw_flag<br>    <br>    mountpoint=$( get_mountpoint_for_pathname "$p" )<br><br>    ## rw_flag: ro / rw<br>    rw_flag=$(<br>      awk -vp=$mountpoint '<br>      {<br>          if ( $1 != "/dev/root" &amp;&amp; $2 == p ) {<br>              str=$4<br>              gsub(",.*", "", str)<br>              print str<br>              exit<br>          }<br>      }' /proc/mounts )<br>      <br>      if [[ $rw_flag == "ro" ]]; then<br>          return 0<br>      else<br>          return 1<br>      fi<br>}<br><br>## 2009-01-14 samli, check if a partition no space left<br>## argv: $mountpoint / $pathname<br>## return true / false<br>is_partition_full()<br>{<br>    local p=$1<br>    local full_flag<br><br>    case $p in<br>    /*)<br>        ;;<br>    *)<br>        return 1<br>        ;;<br>    esac<br>    <br>    ## check inode and data area<br>    full_flag=$( <br>      { df -Pi "$p"; df -Pk "$p"; } |<br>       awk '! /^Filesystem/ {<br>         usage = $(NF-1) + 0<br>         if ( usage == 100 ) {<br>           print "Y"<br>           exit<br>         }<br>       }'<br>     )<br><br>    if [[ $full_flag == "Y" ]]; then<br>	    return 0<br>    else<br>	    return 1<br>    fi<br>}  <br><br>## find the username we added manually<br>## see man shadow to find the detail of the policy<br>find_non_sys_user()<br>{<br><br>    # need root privilege to access '/etc/shadow'<br>    (( UID == 0 )) || return 1<br><br>    perl -we '<br>    use strict;<br>    my @users;<br>    my $fd;<br>    my ( $user, $pass, $uid );<br>    <br>    ## find the username having password<br>    open ($fd, "&lt;", "/etc/shadow") or die "Can not open /etc/shadow\n";<br>    while (&lt;$fd&gt;) {<br>        ($user, $pass ) = (split ":")[0,1];<br>        next if $user eq "root";<br>    <br>        if ( $pass =~ m{ [a-zA-Z0-9/\$] }x ) {<br>            push @users, $user;<br>        }            <br>        elsif ( $pass eq "" ) {<br>            push @users, $user;<br>        }<br>    }<br>    close $fd or die "Can not close $fd\n";<br><br>    ## find the username having uid &gt;= normal uid<br>    open ($fd, "&lt;", "/etc/passwd") or die "Can not open /etc/passwd\n";<br>    while (&lt;$fd&gt;) {<br>        ($user, $uid ) = (split ":")[0,2];<br>        next if $user eq "root";<br>        next if $user eq "nobody";<br>    <br>        if ( $uid &gt;= 1000 ) { ## should  read this val from /etc/login.defs<br>            push @users, $user unless grep { /\b$user\b/ }  @users;<br>        }<br>        elsif ( $uid == 0 ) { ## make sure dangerous user with uid = 0<br>            push @users, $user unless grep { /\b$user\b/ }  @users;<br>        }<br>    }<br>    close $fd or die "Can not close $fd\n";<br><br>    for my $u (sort @users) {<br>        print "$u", " ";<br>    }<br>    '<br>}<br><br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## ------------------------ KERNELL ------------------------<br>## check if kernel supports iptables<br>## return true / false<br>kernel_support_iptables()<br>{<br>    iptables -L -n &amp;&gt; /dev/null<br>}<br><br>## check if kernel supports ip conntrack<br>## return true / false<br>kernel_support_state()<br>{<br>    ## [[ -f /proc/sys/net/ipv4/ip_conntrack_max ]]<br>    [[ -f /proc/net/ip_conntrack ]]<br>}<br><br>## check if kernel supports lvs-rs by checking tunl interface <br>## return true / false<br>kernel_support_rs()<br>{<br>    /sbin/ifconfig tunl0 &amp;&gt; /dev/null<br>}<br><br>## check if kernel supports lvs-ld<br>## return true / false<br>kernel_support_ld()<br>{<br>    kernel_support_rs        || return 1<br>    [[ -f /proc/net/ip_vs ]] || return 1<br><br>    return 0<br>}<br><br>## 2009-03-25, get the label name of stateful kernel from lilo.conf<br>#+ but do not change 2.4-&gt;2.6 or 2.6-&gt;2.4 unthinkingly, nic name may change after reboot<br>## argv: 2.4 / 2.6<br>get_state_label_for_slk()<br>{<br>    ver=$1<br><br>    case $ver in<br>        2.4)    ##<br>            grep -m1 -E 'vmlinuz-2\.4.*STATE' /etc/lilo.conf -A4 |<br>              awk -F= '/label/{ print $2 }'                      |<br>              trim<br>            ;;<br>        2.6)<br>            grep -m1 -E 'vmlinuz-2\.6.*STATE' /etc/lilo.conf -A4 |<br>              awk -F= '/label/{ print $2 }'                      |<br>              trim<br>            ;;<br>        *)<br>            return 1<br>            ;;<br>    esac<br>}<br><br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## ------------------------ tarball ------------------------<br><br>## get tarball dirname,  /1/2/3/abc.tar.bz -&gt; abc<br>## argv: $path_to_tarballname<br>## return dirname<br>get_tarball_dirname()<br>{<br>    local tb="$1"<br>    case $tb in<br>        *.tar.bz2|*.tar.gz)<br>            echo $tb | sed -e 's@.*/@@g' -e 's@\.tar\.\(bz2\|gz\)$@@'<br>            ;;<br>        *.tgz|*.tbz)<br>            echo $tb | sed -e 's@.*/@@g' -e 's@\.\(tbz\|tgz\)$@@'<br>            ;;<br>        *.tar)<br>            echo $tb | sed -e 's@.*/@@g' -e 's@\.tar$@@'<br>            ;;<br>        *)<br>            echo $tb<br>            return 1<br>            ;;<br>    esac<br>}<br><br>## argv: $path_to_tarballname<br>## return bzip2 / gzip / tar<br>get_tarball_type()<br>{<br>    if file   "$1" | grep -Fq 'bzip2 compressed data'; then<br>        echo bzip2 <br>    elif file "$1" | grep -Fq 'gzip compressed data'; then<br>        echo gzip<br>    elif file "$1" | grep -Fq "POSIX tar archive"; then<br>        echo tar<br>    else<br>        return 1<br>    fi<br>}<br><br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## --------------------------- NUM -------------------------<br><br>## a simple int calculater<br>## argv: "$math_expression"<br>## example: calculate "10 / 2"<br>calculate()<br>{<br>    local expr=$@<br><br>    if which bc &amp;&gt;/dev/null; then<br>        echo "scale = 0; $expr" | bc<br>    elif which perl &amp;&gt;/dev/null; then<br>        echo "$expr" | perl -lne ' print int (eval) '<br>    else<br>        echo $(( $expr ))<br>    fi<br>}<br><br>## support float<br>calculate2()<br>{<br>    local expr=$@<br><br>    if which bc &amp;&gt;/dev/null; then<br>        echo "scale = 2; $expr" | bc<br>    elif which perl &amp;&gt;/dev/null; then<br>        echo "$expr" | perl -lne ' printf ("%0.2f",  (eval) ) '<br>    else    ## may try awk here<br>        return 1<br>    fi<br>}<br>## check if argv1 &gt;= argv2<br>## argv1: $num_1<br>## argv2: $num_2<br>compare_two_num()<br>{<br>    if (( $# != 2 )); then<br>        return 1<br>    fi<br><br>    ## hope perl is install in every OS ...<br>    perl -we ' my ($v1, $v2) = @ARGV; exit ( $v1 &gt;= $v2 ? 0 : 1 ) ' $1 $2<br>}<br><br>## get a random num<br>## argv: $max, optionall<br>get_a_random_num()<br>{<br>    local max=$1<br>    local rand=0<br><br>    if [[ -z $max ]]; then<br>        echo $(( RANDOM + 1 ))   ## 1 ~ 32768, see man bash<br>    else<br>        # echo $RANDOM$RANDOM % $1 | perl -lne ' print eval '<br>        while (( rand == 0 )); do<br>            ## 3276732767 &lt; ( 2^32 = 4294967296 )<br>            rand=$( calculate "( $RANDOM$RANDOM + $RANDOM + $RANDOM ) % $max" )<br>        done<br>        echo $rand<br>    fi<br>}<br><br>## get ntp time offset<br>## sorry to hear that ntpdate is deprecated in opensuse 11.1<br>get_ntp_offset()<br>{<br>    local NTP_SERVER="pool.ntp.org"<br>    local offset<br><br>    ## to speed up, just query one server every time<br>    ## so , the ntp server must be reliable<br>    for srv in $NTP_SERVER; do<br>        offset=$( <br>            /usr/sbin/ntpdate -q $NTP_SERVER 2&gt; /dev/null  |<br>            awk '/time server.*sec$/ { print $( NF -1 ) }' |<br>            sed 's/-//' ## get abs val<br>        )<br><br>        if [[ -n $offset ]]; then<br>            echo $offset<br>            return 0<br>        fi<br>    done<br><br>    return 1<br>}<br><br>## ---------------------------------------------------------<br><br><br><br><br><br><br>## ------------------------- MISC --------------------------<br><br>dump_cron()<br>{<br>    local user=$1<br><br>    local user_flag<br><br>    if [[ -n $user ]]; then<br>        if (( UID != 0 )); then<br>            return 1<br>        fi<br><br>        user_flag="-u $user"<br>    fi<br><br>    crontab $user_flag -l | <br>     perl -lne ' print if ( ( $. &gt; 3 ) || ( $. &lt;= 3 &amp;&amp; /^[^#] /) ) ' <br>}<br><br>## add a cron jobs line to crontab, with 'force' arg to add a comment line<br>## example: add_cron "### sync clock every hour" "force"<br>## example: add_cron "30 * * * * /usr/sbin/ntpdate 172.23.32.142 &amp;&gt; /dev/null"<br>## example: add_cron "30 * * * * /usr/sbin/ntpdate 172.23.32.142 &amp;&gt; /dev/null" "mqq"<br>add_cron()<br>{<br>    local cmd=$1<br>    local force=$2<br>    local user=$3<br>    local key<br>    local is_comment<br><br>    local user_flag<br><br>    if [[ -n $user ]]; then<br>        if (( UID != 0 )); then<br>            return 1<br>        fi<br><br>        user_flag="-u $user"<br>    fi<br><br>    # good to use absolute path in crontab<br>    local c<br>    for c in $cmd; do<br>        case $c in<br>            /*)<br>                ## key=$( basename $c )<br>                key=$c<br>                break<br>                ;;<br>        esac<br>    done<br><br>    if ! [[ $force == "force" || $force == "FORCE" ]]; then<br>        if [[ -z "$key" ]]; then<br>            warn "failed, [$cmd] not use abs_path to command"<br>            return 1<br>        fi<br><br>        if [[ ! -x "$c" ]]; then<br>            warn "failed, [$c] not executable"<br>            return 1<br>        fi<br><br>        if crontab $user_flag -l | grep -F -v '#' | grep -Fqw -- "$key"; then<br>            warn "failed, keyword [$key] found in crontab already"<br>            return 1<br>        fi<br>    fi<br><br>    if echo "$cmd" | grep -Eq '^[[:blank:]]+#'; then<br>        is_comment=yes<br>    fi<br><br>    # update crontab<br>    # crontab $user_flag -l | perl -lne ' print if ( ( $. &gt; 3 ) || ( $. &lt;= 3 &amp;&amp; /^[^#] /) ) ' |<br>    dump_cron "$user" |<br>    {   <br>      cat <br>      [[ $is_comment == "yes" ]] || echo "## DO NOT DELETE! [ $key ] added by AMC at $(date '+%F %T')"<br>      echo  "$cmd"<br>    } | crontab - $user_flag<br>}    <br><br>comment_cron()<br>{<br>    local key=$1<br>    local user=$2<br><br>    local user_flag<br><br>    [[ -n $key ]] || return 1<br><br>    if [[ -n $user ]]; then<br>        if (( UID != 0 )); then<br>            return 1<br>        fi<br><br>        user_flag="-u $user"<br>    fi<br><br>    # crontab $user_flag -l | perl -lne ' print if ( ( $. &gt; 3 ) || ( $. &lt;= 3 &amp;&amp; /^[^#] /) ) ' |<br>    dump_cron "$user" |<br>     sed "/$key/ s/^/## /" | crontab - $user_flag<br>}<br><br>del_cron()<br>{<br>    local key=$1<br>    local user=$2<br><br>    local user_flag<br><br>    [[ -n $key ]] || return 1<br><br>    if [[ -n $user ]]; then<br>        if (( UID != 0 )); then<br>            return 1<br>        fi<br><br>        user_flag="-u $user"<br>    fi<br><br>    ## nonsense 3 lines header<br>    # crontab $user_flag -l | perl -lne ' print if ( ( $. &gt; 3 ) || ( $. &lt;= 3 &amp;&amp; /^[^#] /) ) ' |<br>    dump_cron "$user" |<br>     grep -v -- "$key" | crontab - $user_flag<br>}<br><br>## trim leading space and tailing space<br>## example: iptables -nvL | trim<br>## example: trim &lt; file<br>trim()<br>{<br>    sed -e 's/^[[:space:]]\+//' -e 's/[[:space:]]\+$//'<br>}<br><br>## check if a string already in a file which is not commented<br>## argv1: $str<br>## argv2: $filename<br>## return true / false<br>is_str_infile()<br>{<br>    local str="$1"<br>    local file="$2"<br><br>    grep -Fv '#' "$file" | grep -Fwq -- "$str"<br>}<br><br>## kill a process if it's running<br>## argv: $app_name<br>try_kill_proc()<br>{<br>    local proc="$1"<br><br>    if killall -0 "$proc" &amp;&gt;/dev/null; then<br>        if killall -9 "$proc"; then<br>            logmsg "found old "$proc" running, kill OK"<br>        else<br>            die "found old "$proc" running, kill FAILED"<br>        fi<br>    fi<br>}<br><br>## to grep multipul times, supposed to be used after a pipe or with read redirection<br>## example: ps -ef | mgrep samli ssh<br>mgrep()<br>{<br>    local key="$1"<br>    local opt=<br><br>    if [[ -z "$key" ]]; then<br>        cat     <br>        return  <br>    fi<br><br>    while [[ ${key:0:1} == '-' ]]; do<br>        opt="$opt $key"<br>        shift<br>        key="$1"<br>    done<br><br>    shift   <br>    grep $opt $key | mgrep "$@"<br>}<br><br><br>## thanks kangkang <br>dectobin()<br>{<br>    local s=$1<br>    local n <br><br>    while (( $s != 0 )); do<br>        n=$(( s % 2 ))$n<br>        s=$(( s / 2 ))<br>    done    <br><br>    echo $n <br>}<br><br>## thanks kangkang <br>cidr_mask()<br>{<br>    local i<br>    local mask=$1<br>    local out<br><br>    for i in $( echo $mask | tr '.' ' ' ); do<br>        out=$out$(dectobin $i)<br>    done<br>    <br>    out=$(echo $out | sed 's/0*$//g' )<br><br>    if echo $out | grep -q 0; then<br>        return 1<br>    fi<br><br>    echo -n $out | wc -c<br>}<br><br>## xor op, usring P$1" <br>## argv[1]: key to xor with<br>## argv[2]: str to xor<br>myxor()<br>{<br>    local key=$1<br>    local str=$2<br><br>    perl -lwe ' <br>        my $key = shift;<br>        $_ = shift;<br>        my @new;<br>        for my $s ( split( "" ) ) {<br>            push @new, chr( (ord $s) ^ $key );<br>        }<br>        print join "", @new;<br>    ' "$key" "$str"<br>}<br><br>## get_name_of_pid()<br>## {<br>##     local pid=$1<br>## <br>##     /bin/ls -l "/proc/$pid/exe" 2&gt;/dev/null<br>## }<br><br>is_dos_file()<br>{<br>    local file=$1<br><br>    file "$file" | grep -q 'with CRLF line terminators'<br>}<br><br>## dos2unix is lost on some servers -_-!<br>my_dos2unix()<br>{<br>    local file=$1<br><br>    if which dos2unix ; then<br>        dos2unix "$file"<br>    else<br>        perl -pi -e 's/\r$//' "$file"<br>    fi &amp;&gt; /dev/null<br>}<br><br>dos2unix_if_necessary()<br>{<br>    local file=$1<br><br>    [[ -f $file ]] || return 1<br><br>    if is_dos_file "$file"; then<br>        my_dos2unix "$file"<br>    else<br>        return 0<br>    fi<br>}<br><br>## find the java dirname without unpacking jdk*.bin<br>## we may return [jdk1.5.0_06] for [jdk-1_5_0_06-linux-i586.bin]<br>get_javadir_from_javabin()<br>{<br>    javabin=$1  ## such as [jdk-1_5_0_06-linux-i586.bin]<br><br>    if [[ -z $javabin ]] || [[ ! -f $javabin ]]; then<br>        return 1<br>    fi<br><br>    grep -m1 -a '^javahome=jdk.*' "$javabin" |<br>      awk -F= '{ print $2 }'<br>}<br><br>## ---------------------------------------------------------<br><br><br><br><br>## ----------------------- PROCESS -------------------------<br><br>## check if a given pid/appname running<br>## argv: pid / appname<br>is_app_running()<br>{<br>    local $p=$1<br>    local RC<br><br>    [[ -n $p ]] || return 1<br>    <br>    ## pid<br>    if [[ -z $( echo $p | tr -d '[0-9]') ]]; then<br>        kill -0 "$p" &amp;&gt; /dev/null<br>        RC=$?<br>    ## app name<br>    else<br>        killall -0 "$p" &amp;&gt; /dev/null<br>        RC=$?<br>    fi<br><br>    return $RC<br>}<br><br>lock_on()<br>{<br>    local f=$1<br>    local freefd=6  ## do not use fd 5<br><br>    ## make sure the file be there<br>    mkdir -p "$( dirname $f )"<br>    touch "$f"<br><br>    ## find a free fd<br>    while (( freefd &lt;= 9 )); do<br>        [[ -L /dev/fd/$freefd ]] || break<br>        (( freefd++ ))<br>    done<br><br>    (( freefd == 10 )) &amp;&amp; return 1<br><br>    ## open the lock file<br>    eval "exec $freefd&lt; \"$f\""<br>}<br><br>is_locked()<br>{<br>    local f=$1<br><br>    fuser "$f" &amp;&gt; /dev/null<br>}<br><br>## -------------------- init global vars -------------------<br><br>## init LLLOCALIP, do not delete following line, logmsg/warn/die use this val<br>LLLOCALIP=$( get_localip )<br><br>## init WORKDIR<br>[[ -n $WORKDIR ]]  || WORKDIR=$( get_workdir )<br><br>## init LLLOG, LLLOGDIR <br>## this val must be used after the logdir created in func logmsg/logmsg_/warn/die<br>[[ -n $LLLOG    ]] || LLLOG="$WORKDIR/log.d/log.$LLLOCALIP"<br>[[ -n $LLLOGDIR ]] || LLLOGDIR=${LLLOG%/*}<br><br>## ---------------------------------------------------------<br></pre>
from:<br><a  href="http://bbs.linuxeden.com/thread-192227-1-1.html">http://bbs.linuxeden.com/thread-192227-1-1.html
</a><br><a  href="http://huan.googlecode.com/svn/bash/func-common.sh">http://huan.googlecode.com/svn/bash/func-common.sh
</a><br><br><img src ="http://www.cppblog.com/beautykingdom/aggbug/114291.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-05-03 22:42 <a href="http://www.cppblog.com/beautykingdom/archive/2010/05/03/114291.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>想挂掉就运行的shell脚本，最好不要去试哈</title><link>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110595.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 26 Mar 2010 09:24:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110595.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/110595.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/110595.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/110595.html</trackback:ping><description><![CDATA[:() { :|:&amp; }; :&nbsp; &nbsp;&nbsp;&nbsp; <br># &lt;--- 這個別亂跑！好奇會死人的！<br>
<br>echo '十人|日一|十十o' | sed 's/.../&amp;\n/g'&nbsp;&nbsp; <br># &lt;--- 跟你講就不聽，再跑這個好了...<img src ="http://www.cppblog.com/beautykingdom/aggbug/110595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-03-26 17:24 <a href="http://www.cppblog.com/beautykingdom/archive/2010/03/26/110595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell版俄罗斯方块</title><link>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110578.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 26 Mar 2010 03:51:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110578.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/110578.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110578.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/110578.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/110578.html</trackback:ping><description><![CDATA[<strong>#!/bin/bash<br><br># Tetris Game<br># 10.21.2003 xhchen&lt;[email]xhchen@winbond.com.tw[/email]&gt;<br><br>#APP declaration<br>APP_NAME="${0##*[\\/]}"<br>APP_VERSION="1.0"<br><br><br>#颜色定义<br>cRed=1<br>cGreen=2<br>cYellow=3<br>cBlue=4<br>cFuchsia=5<br>cCyan=6<br>cWhite=7<br>colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)<br><br>#位置和大小<br>iLeft=3<br>iTop=2<br>((iTrayLeft = iLeft + 2))<br>((iTrayTop = iTop + 1))<br>((iTrayWidth = 10))<br>((iTrayHeight = 15))<br><br>#颜色设置<br>cBorder=$cGreen<br>cScore=$cFuchsia<br>cScoreValue=$cCyan<br><br>#控制信号<br>#改游戏使用两个进程，一个用于接收输入，一个用于游戏流程和显示界面;<br>#当前者接收到上下左右等按键时，通过向后者发送signal的方式通知后者。<br>sigRotate=25<br>sigLeft=26<br>sigRight=27<br>sigDown=28<br>sigAllDown=29<br>sigExit=30<br><br>#七中不同的方块的定义<br>#通过旋转，每种方块的显示的样式可能有几种<br>box0=(0 0 0 1 1 0 1 1)<br>box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)<br>box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)<br>box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)<br>box4=(0 1 0 2 1 1 2 1 1 0 1 1 1 2 2 2 0 1 1 1 2 0 2 1 0 0 1 0 1 1 1 2)<br>box5=(0 1 1 1 2 1 2 2 1 0 1 1 1 2 2 0 0 0 0 1 1 1 2 1 0 2 1 0 1 1 1 2)<br>box6=(0 1 1 1 1 2 2 1 1 0 1 1 1 2 2 1 0 1 1 0 1 1 2 1 0 1 1 0 1 1 1 2)<br>#所有其中方块的定义都放到box变量中<br>box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})<br>#各种方块旋转后可能的样式数目<br>countBox=(1 2 2 2 4 4 4)<br>#各种方块再box数组中的偏移<br>offsetBox=(0 1 3 5 7 11 15)<br><br>#每提高一个速度级需要积累的分数<br>iScoreEachLevel=50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #be greater than 7<br><br>#运行时数据<br>sig=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #接收到的signal<br>iScore=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #总分<br>iLevel=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #速度级<br>boxNew=()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #新下落的方块的位置定义<br>cBoxNew=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #新下落的方块的颜色<br>iBoxNewType=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #新下落的方块的种类<br>iBoxNewRotate=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #新下落的方块的旋转角度<br>boxCur=()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #当前方块的位置定义<br>cBoxCur=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #当前方块的颜色<br>iBoxCurType=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #当前方块的种类<br>iBoxCurRotate=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #当前方块的旋转角度<br>boxCurX=-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #当前方块的x坐标位置<br>boxCurY=-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #当前方块的y坐标位置<br>iMap=()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #背景方块图表<br><br>#初始化所有背景方块为-1, 表示没有方块<br>for ((i = 0; i &lt; iTrayHeight * iTrayWidth; i++)); do iMap[$i]=-1; done<br><br><br>#接收输入的进程的主函数<br>function RunAsKeyReceiver()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local pidDisplayer key aKey sig cESC sTTY<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pidDisplayer=$1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aKey=(0 0 0)<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cESC=`echo -ne "\033"`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cSpace=`echo -ne "\040"`<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #保存终端属性。在read -s读取终端键时，终端的属性会被暂时改变。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #如果在read -s时程序被不幸杀掉，可能会导致终端混乱，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #需要在程序退出时恢复终端属性。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sTTY=`stty -g`<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #捕捉退出信号<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trap "MyExit;" INT TERM<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trap "MyExitNoSub;" $sigExit<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #隐藏光标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[?25l"<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while :<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #读取输入。注-s不回显，-n读到一个字符立即返回<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read -s -n 1 key<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aKey[0]=${aKey[1]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aKey[1]=${aKey[2]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aKey[2]=$key<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sig=0<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #判断输入了何种键<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [[ $key == $cESC &amp;&amp; ${aKey[1]} == $cESC ]]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #ESC键<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyExit<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ ${aKey[0]} == $cESC &amp;&amp; ${aKey[1]} == "[" ]]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [[ $key == "A" ]]; then sig=$sigRotate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&lt;向上键&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ $key == "B" ]]; then sig=$sigDown&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&lt;向下键&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ $key == "D" ]]; then sig=$sigLeft&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&lt;向左键&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ $key == "C" ]]; then sig=$sigRight&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&lt;向右键&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #W, w<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ $key == "S" || $key == "s" ]]; then sig=$sigDown&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #S, s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeft&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #A, a<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ $key == "D" || $key == "d" ]]; then sig=$sigRight&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #D, d<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ "[$key]" == "[]" ]]; then sig=$sigAllDown&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #空格键<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif [[ $key == "Q" || $key == "q" ]]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Q, q<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyExit<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [[ $sig != 0 ]]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #向另一进程发送消息<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kill -$sig $pidDisplayer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>}<br><br>#退出前的恢复<br>function MyExitNoSub()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local y<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #恢复终端属性<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stty $sTTY<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((y = iTop + iTrayHeight + 4))<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示光标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -e "\033[?25h\033[${y};0H"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit<br>}<br><br><br>function MyExit()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #通知显示进程需要退出<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kill -$sigExit $pidDisplayer<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyExitNoSub<br>}<br><br><br>#处理显示和游戏流程的主函数<br>function RunAsDisplayer()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local sigThis<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitDraw<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #挂载各种信号的处理函数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trap "sig=$sigRotate;" $sigRotate<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trap "sig=$sigLeft;" $sigLeft<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trap "sig=$sigRight;" $sigRight<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trap "sig=$sigDown;" $sigDown<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trap "sig=$sigAllDown;" $sigAllDown<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trap "ShowExit;" $sigExit<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while :<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #根据当前的速度级iLevel不同，设定相应的循环的次数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((i = 0; i &lt; 21 - iLevel; i++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep 0.02<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigThis=$sig<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sig=0<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #根据sig变量判断是否接受到相应的信号<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((sigThis == sigRotate)); then BoxRotate;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #旋转<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif ((sigThis == sigLeft)); then BoxLeft;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #左移一列<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif ((sigThis == sigRight)); then BoxRight;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #右移一列<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif ((sigThis == sigDown)); then BoxDown;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #下落一行<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif ((sigThis == sigAllDown)); then BoxAllDown;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #下落到底<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #kill -$sigDown $$<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BoxDown&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #下落一行<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>}<br><br><br>#BoxMove(y, x), 测试是否可以把移动中的方块移到(x, y)的位置, 返回0则可以, 1不可以<br>function BoxMove()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local j i x y xTest yTest<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yTest=$1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xTest=$2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; 8; j += 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = j + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((y = ${boxCur[$j]} + yTest))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((x = ${boxCur[$i]} + xTest))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (( y &lt; 0 || y &gt;= iTrayHeight || x &lt; 0 || x &gt;= iTrayWidth))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #撞到墙壁了<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((${iMap[y * iTrayWidth + x]} != -1 ))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #撞到其他已经存在的方块了<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}<br><br><br>#将当前移动中的方块放到背景方块中去,<br>#并计算新的分数和速度级。(即一次方块落到底部)<br>function Box2Map()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local j i x y xp yp line<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #将当前移动中的方块放到背景方块中去<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; 8; j += 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = j + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((y = ${boxCur[$j]} + boxCurY))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((x = ${boxCur[$i]} + boxCurX))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = y * iTrayWidth + x))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iMap[$i]=$cBoxCur<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #消去可被消去的行<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line=0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; iTrayWidth * iTrayHeight; j += iTrayWidth))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((i = j + iTrayWidth - 1; i &gt;= j; i--))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((${iMap[$i]} == -1)); then break; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((i &gt;= j)); then continue; fi<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((line++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((i = j - 1; i &gt;= 0; i--))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((x = i + iTrayWidth))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iMap[$x]=${iMap[$i]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((i = 0; i &lt; iTrayWidth; i++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iMap[$i]=-1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((line == 0)); then return; fi<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #根据消去的行数line计算分数和速度级<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((x = iLeft + iTrayWidth * 2 + 7))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((y = iTop + 11))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((iScore += line * 2 - 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示新的分数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[1m\033[3${cScoreValue}m\033[${y};${x}H${iScore}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((iScore % iScoreEachLevel &lt; line * 2 - 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((iLevel &lt; 20))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((iLevel++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((y = iTop + 14))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示新的速度级<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[3${cScoreValue}m\033[${y};${x}H${iLevel}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[0m"<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #重新显示背景方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((y = 0; y &lt; iTrayHeight; y++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((yp = y + iTrayTop + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((xp = iTrayLeft + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = y * iTrayWidth))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[${yp};${xp}H"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((x = 0; x &lt; iTrayWidth; x++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((j = i + x))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((${iMap[$j]} == -1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "&nbsp; "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[1m\033[7m\033[3${iMap[$j]}m\033[4${iMap[$j]}m[]\033[0m"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>}<br><br><br>#下落一行<br>function BoxDown()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local y s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((y = boxCurY + 1))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #新的y坐标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if BoxMove $y $boxCurX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #测试是否可以下落一行<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s="`DrawCurBox 0`"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #将旧的方块抹去<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((boxCurY = y))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s="$s`DrawCurBox 1`"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示新的下落后方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne $s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #走到这儿, 如果不能下落了<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Box2Map&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #将当前移动中的方块贴到背景方块中<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RandomBox&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #产生新的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>}<br><br>#左移一列<br>function BoxLeft()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local x s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((x = boxCurX - 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if BoxMove $boxCurY $x<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=`DrawCurBox 0`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((boxCurX = x))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=$s`DrawCurBox 1`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne $s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>}<br><br>#右移一列<br>function BoxRight()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local x s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((x = boxCurX + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if BoxMove $boxCurY $x<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=`DrawCurBox 0`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((boxCurX = x))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=$s`DrawCurBox 1`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne $s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>}<br><br><br>#下落到底<br>function BoxAllDown()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local k j i x y iDown s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iDown=$iTrayHeight<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #计算一共需要下落多少行<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; 8; j += 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = j + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((y = ${boxCur[$j]} + boxCurY))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((x = ${boxCur[$i]} + boxCurX))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((k = y + 1; k &lt; iTrayHeight; k++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = k * iTrayWidth + x))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (( ${iMap[$i]} != -1)); then break; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((k -= y + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (( $iDown &gt; $k )); then iDown=$k; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=`DrawCurBox 0`&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #将旧的方块抹去<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((boxCurY += iDown))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=$s`DrawCurBox 1`&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示新的下落后的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne $s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Box2Map&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #将当前移动中的方块贴到背景方块中<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RandomBox&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #产生新的方块<br>}<br><br><br>#旋转方块<br>function BoxRotate()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local iCount iTestRotate boxTest j i s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iCount=${countBox[$iBoxCurType]}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #当前的方块经旋转可以产生的样式的数目<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #计算旋转后的新的样式<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((iTestRotate = iBoxCurRotate + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((iTestRotate &gt;= iCount))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((iTestRotate = 0))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #更新到新的样式, 保存老的样式(但不显示)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j &lt; 8; j++, i++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxTest[$j]=${boxCur[$j]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxCur[$j]=${box[$i]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if BoxMove $boxCurY $boxCurX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #测试旋转后是否有空间放的下<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #抹去旧的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; 8; j++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxCur[$j]=${boxTest[$j]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=`DrawCurBox 0`<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #画上新的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j &lt; 8; j++, i++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxCur[$j]=${box[$i]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=$s`DrawCurBox 1`<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne $s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iBoxCurRotate=$iTestRotate<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #不能旋转，还是继续使用老的样式<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; 8; j++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxCur[$j]=${boxTest[$j]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>}<br><br><br>#DrawCurBox(bDraw), 绘制当前移动中的方块, bDraw为1, 画上, bDraw为0, 抹去方块。<br>function DrawCurBox()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local i j t bDraw sBox s<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bDraw=$1<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=""<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (( bDraw == 0 ))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sBox="\040\040"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sBox="[]"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=$s"\033[1m\033[7m\033[3${cBoxCur}m\033[4${cBoxCur}m"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; 8; j += 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = iTrayTop + 1 + ${boxCur[$j]} + boxCurY))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t = iTrayLeft + 1 + 2 * (boxCurX + ${boxCur[$j + 1]})))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #\033[y;xH, 光标到(x, y)处<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=$s"\033[${i};${t}H${sBox}"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=$s"\033[0m"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -n $s<br>}<br><br><br>#更新新的方块<br>function RandomBox()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local i j t<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #更新当前移动的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iBoxCurType=${iBoxNewType}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iBoxCurRotate=${iBoxNewRotate}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cBoxCur=${cBoxNew}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; ${#boxNew[@]}; j++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxCur[$j]=${boxNew[$j]}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示当前移动的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (( ${#boxCur[@]} == 8 ))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #计算当前方块该从顶端哪一行"冒"出来<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0, t = 4; j &lt; 8; j += 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((${boxCur[$j]} &lt; t)); then t=${boxCur[$j]}; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((boxCurY = -t))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 1, i = -4, t = 20; j &lt; 8; j += 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((${boxCur[$j]} &gt; i)); then i=${boxCur[$j]}; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((${boxCur[$j]} &lt; t)); then t=${boxCur[$j]}; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((boxCurX = (iTrayWidth - 1 - i - t) / 2))<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示当前移动的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne `DrawCurBox 1`<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #如果方块一出来就没处放，Game over!<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ! BoxMove $boxCurY $boxCurX<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kill -$sigExit ${PPID}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ShowExit<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #清除右边预显示的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; 4; j++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = iTop + 1 + j))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t = iLeft + 2 * iTrayWidth + 7))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[${i};${t}H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #随机产生新的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((iBoxNewType = RANDOM % ${#offsetBox[@]}))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((iBoxNewRotate = RANDOM % ${countBox[$iBoxNewType]}))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0, i = (${offsetBox[$iBoxNewType]} + $iBoxNewRotate) * 8; j &lt; 8; j++, i++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boxNew[$j]=${box[$i]};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((cBoxNew = ${colorTable[RANDOM % ${#colorTable[@]}]}))<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示右边预显示的方块<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[1m\033[7m\033[3${cBoxNew}m\033[4${cBoxNew}m"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((j = 0; j &lt; 8; j += 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((i = iTop + 1 + ${boxNew[$j]}))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t = iLeft + 2 * iTrayWidth + 7 + 2 * ${boxNew[$j + 1]}))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[${i};${t}H[]"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[0m"<br>}<br><br><br>#初始绘制<br>function InitDraw()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clear<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RandomBox&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #随机产生方块，这时右边预显示窗口中有方快了<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RandomBox&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #再随机产生方块，右边预显示窗口中的方块被更新，原先的方块将开始下落<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local i t1 t2 t3<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示边框<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[1m"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[3${cBorder}m\033[4${cBorder}m"<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t2 = iLeft + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t3 = iLeft + iTrayWidth * 2 + 3))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((i = 0; i &lt; iTrayHeight; i++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t1 = i + iTop + 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[${t1};${t2}H||"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[${t1};${t3}H||"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t2 = iTop + iTrayHeight + 2))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ((i = 0; i &lt; iTrayWidth + 2; i++))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t1 = i * 2 + iLeft + 1))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[${iTrayTop};${t1}H=="<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[${t2};${t1}H=="<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[0m"<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #显示"Score"和"Level"字样<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[1m"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t1 = iLeft + iTrayWidth * 2 + 7))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t2 = iTop + 10))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[3${cScore}m\033[${t2};${t1}HScore"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t2 = iTop + 11))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[3${cScoreValue}m\033[${t2};${t1}H${iScore}"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t2 = iTop + 13))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[3${cScore}m\033[${t2};${t1}HLevel"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((t2 = iTop + 14))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[3${cScoreValue}m\033[${t2};${t1}H${iLevel}"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -ne "\033[0m"<br>}<br><br><br>#退出时显示GameOVer!<br>function ShowExit()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local y<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((y = iTrayHeight + iTrayTop + 3))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -e "\033[${y};0HGameOver!\033[0m"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit<br>}<br><br><br>#显示用法.<br>function Usage<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cat &lt;&lt; EOF<br>Usage: $APP_NAME<br>Start tetris game.<br><br>&nbsp; -h, --help&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; display this help and exit<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --version&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output version information and exit<br>EOF<br>}<br><br><br>#游戏主程序在这儿开始.<br>if [[ "$1" == "-h" || "$1" == "--help" ]]; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Usage<br>elif [[ "$1" == "--version" ]]; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "$APP_NAME $APP_VERSION"<br>elif [[ "$1" == "--show" ]]; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #当发现具有参数--show时，运行显示函数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RunAsDisplayer<br>else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bash $0 --show&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #以参数--show将本程序再运行一遍<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RunAsKeyReceiver $!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #以上一行产生的进程的进程号作为参数<br>fi<br><br><br>from:<br>http://bbs.chinaunix.net/thread-184858-1-1.html<br></strong><img src ="http://www.cppblog.com/beautykingdom/aggbug/110578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-03-26 11:51 <a href="http://www.cppblog.com/beautykingdom/archive/2010/03/26/110578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ANSI控制码</title><link>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110577.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 26 Mar 2010 03:41:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110577.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/110577.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/03/26/110577.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/110577.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/110577.html</trackback:ping><description><![CDATA[ANSI控制码的说明<br>
例如:<br>
&nbsp;&nbsp;echo -ne "\33[32m" 可以将字符的显示颜色改为绿色<br>
&nbsp;&nbsp;echo -ne "\33[3;1H" 可以将光标移到第3行第1列处<br>
具体的摘抄一些如下：<br>
\33[0m&nbsp;&nbsp;关闭所有属性<br>
\33[1m&nbsp;&nbsp;设置高亮度<br>
\33[4m&nbsp;&nbsp;下划线<br>
\33[5m&nbsp;&nbsp;闪烁<br>
\33[7m&nbsp;&nbsp;反显<br>
\33[8m&nbsp;&nbsp;消隐<br>
\33[30m -- \33[37m&nbsp;&nbsp;设置前景色<br>
\33[40m -- \33[47m&nbsp;&nbsp;设置背景色<br>
\33[nA&nbsp;&nbsp;光标上移n行<br>
\33[nB&nbsp;&nbsp;光标下移n行<br>
\33[nC&nbsp;&nbsp;光标右移n行<br>
\33[nD&nbsp;&nbsp;光标左移n行<br>
\33[y;xH设置光标位置<br>
\33[2J&nbsp;&nbsp;清屏<br>
\33[K&nbsp; &nbsp;清除从光标到行尾的内容<br>
\33[s&nbsp; &nbsp;保存光标位置<br>
\33[u&nbsp; &nbsp;恢复光标位置<br>
\33[?25l&nbsp;&nbsp;隐藏光标<br>
\33[?25h&nbsp;&nbsp;显示光标<br><br>不同的shell,转义是不同的,<br>
/home/lee#echo "\\033[32mddd"<br>
<font color="green">ddd<br>
/home/lee#<br>
/home/lee#bash<br>
/home/lee#echo "\\033[33maddd"<br>
\033[33maddd<br>
/home/lee#exit<br>
/home/lee#echo "\\033[34maddd"</font><br>
<font color="blue">addd<br>
/home/lee#echo $0<br>
-ksh<br>
/home/lee#<br><br>from:<br>http://bbs.chinaunix.net/thread-207837-1-1.html<br></font><img src ="http://www.cppblog.com/beautykingdom/aggbug/110577.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-03-26 11:41 <a href="http://www.cppblog.com/beautykingdom/archive/2010/03/26/110577.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell基础二：查找技巧,find及xargs的使用</title><link>http://www.cppblog.com/beautykingdom/archive/2010/03/17/109880.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Wed, 17 Mar 2010 03:14:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/03/17/109880.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/109880.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/03/17/109880.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/109880.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/109880.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Normal07.8 磅02falsefalsefalseMicrosoftInternetExplorer4st1\:*{behavior:url(#ieooui) }/* Style Definitions */table.MsoNormalT...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2010/03/17/109880.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/109880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-03-17 11:14 <a href="http://www.cppblog.com/beautykingdom/archive/2010/03/17/109880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>五大非常见Linux命令</title><link>http://www.cppblog.com/beautykingdom/archive/2010/03/06/109024.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sat, 06 Mar 2010 03:26:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/03/06/109024.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/109024.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/03/06/109024.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/109024.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/109024.html</trackback:ping><description><![CDATA[<p>Linux有大量的命令行工具，从每天都会使用的ls、cd以及ps这些工具，到您可能还没有使用过，或者甚至没有听说过的不常见的工具。</p>
<p>　　我们将看一下五个不常见，但可以让您的使用更轻松的工具。我们会简单地看看每一个命令及其标志和参数，但请不要忘了对每一个命令使用man命令，去获取所有可能的标志和参数信息。</p>
<p><strong> 　　logsave</strong> </p>
<p>　　我们将查看的第一个工具是logsave。logsave命令可以将一个命令的输出保存到一个日志文件中：</p>
<p>　　$ logsave /var/log/partsize df &#8211;h</p>
<p>　　这里，logsave命令将df命令的输出保存到/var/log/partsize文件中，同时会添加一个时间戳并将命令的执行结果输出到标准输出。</p>
<p>
听起来并不是那么的有趣，是吗？logsave特殊的魔力在于，如果文件，在这个例子中是/var/log/partsize，并不存在，那么
logsave会在内存中将数据进行排队，等待该文件的产生。对于在启动过程中，当您在对一个还没有挂载上的分区进行写操作时，用logsave去跟踪命
令的执行输出是非常有用的。为了保存可能会丢失的命令行输出，我经常在自动配置和引导过程中，使用logsave。</p>
<p><strong> 　　diff3</strong> </p>
<p>
下一个工具是diff3命令。您可能已经使用过diff命令去生成文件之间的差异。相对于diff的两个文件，diff3可以对三个文件执行同样的功
能，但包括diff中的一些更复杂的选项。让我们看一个简单的例子。我们有三个文件：cat、dog以及mouse，它们各自包含一个字符串。我们可以用
diff3对所有的三个文件进行比较：</p>
<p>$ diff3 dog cat mouse<br>====<br>1:1c<br>&nbsp; This is a dog<br>2:1c<br>&nbsp; This is a cat<br>3:1c<br>&nbsp; This is a mouse</p>
<p>　　diff3命令显示了三个文件中不同的字符串。您也可以用&#8220;-&#8221;标记代表一个文件。这将会把标准输入和其他文件进行比较。 </p>
<p>　　您也可以使用-A标记，在所有的文件里面，去合并不同，并对任何冲突之处进行高亮显示。</p>
<p>$ diff3 -A dog cat mouse<br>1a<br>||||||| cat<br>This is a cat<br>=======<br>This is a mouse<br>&gt;&gt;&gt;&gt;&gt;&gt;&gt; mouse<br>.<br>0a<br>&lt;&lt;&lt;&lt;&lt;&lt;&lt; dog<br>.</p>
<p><strong> 　　pstree</strong> </p>
<p>
您可能已经在您的主机上，使用过ps去列出所有的进程。但您可能还没有听说过pstree——一个用于以树的形式显示您的进程的命令。一个进程或者从
init进程，从一个您可以指定的PID（进程ID）分支出来，或者从一个您可以指定的用户分支出来。每一个进程及其子进程如下所示：</p>
<p align="center"><img id="eWebEditor_TempElement_Img" style="cursor: pointer;" onclick="showimg(this.src);return false;" alt="pstree命令" src="http://ttcma.techtarget.com.cn/UpLoad/ArticlePic/2010-01-28-14-31-04.jpg" border="0" width="500"><br>&nbsp;<br>　　pstree命令也包括一些您可以使用的命令行标志。比如-a标志会显示进程所使用的命令行，而-p标志会在树中添加进程的进程ID。</p>
<p><strong> 　　nl</strong> </p>
<p>　　nl命令很少有人知道，但却可以执行一个很漂亮的小功能——它在输出中添加行号。让我们看一个简单的例子，对一个叫做dog的文件执行nl命令。</p>
<p>$ nl dog<br>1 This is a dog<br>2 This is not a dog</p>
<p>　　您可以看到nl获取了dog文件的内容，并在输出中添加了行号。然后，您可以将这些输出通过管道放到一个新文件中。</p>
<p>　　$ nl dog &gt; dog_numbered </p>
<p>　　然后，我们就可以显示这个带有新的行号内容的文件：</p>
<p>$ cat dog_numbered<br>1 This is a dog<br>2 This is not a dog</p>
<p><strong> 　　split</strong> </p>
<p>　　我们要看的最后一个命令是split。split命令通常基于尺寸将文件分割为多个片段。我使用这个命令,去将大的日志文件分割为更好管理的日志片段，例如：</p>
<p>　　$ split --bytes=1m /tmp/largelogfile /tmp/smallerfile</p>
<p>　　split命令有根据字节数和行数对文件进行分割的参数。这里,我们通过指定--bytes=1m参数，将大的日志文件分割为1M字节的块（您可以指定b去代表字节，k代表千字节，g代表十亿字节）。</p>
<p>　　我们可以像这样根据行数对文件进行分割：</p>
<p>　　$ split --lines=1000 /tmp/largelogfile /tmp/smallerfile</p>
<p>　　这里，文件会被分为多个1000行的块。 </p>
<p>
在我们的例子中，会将每个块都存在/tmp目录下，其文件名会包含一个前缀smallerfile。第一个文件为smallerfileaa，第二个是
smallerfileab等等。您也可以使用-d标记，去使用数字而不是通过字母的增长来对块进行计数。最后，除了可以指定一个文件，您也可以使用
&#8220;-&#8221;去让split命令以标准输入为输入，并分割为独立的文件。</p>
<br>from:<br>http://www.searchsv.com.cn/showcontent_31396.htm
<br><br><img src ="http://www.cppblog.com/beautykingdom/aggbug/109024.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-03-06 11:26 <a href="http://www.cppblog.com/beautykingdom/archive/2010/03/06/109024.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LINUX命令xargs的简单应用及举例</title><link>http://www.cppblog.com/beautykingdom/archive/2010/02/17/107949.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 16 Feb 2010 20:11:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/02/17/107949.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/107949.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/02/17/107949.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/107949.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/107949.html</trackback:ping><description><![CDATA[<p><font size="4" face="Arial">xargs<br><font color="#ff0000">大多数 Linux 命令都会产生输出：文件列表、字符串列表等。但如果要使用其他某个命令并将前一个命令的输出作为参数该怎么办？</font>例
如，file 命令显示文件类型（可执行文件、ascii 文本等）；您可以处理输出，使其仅显示文件名，现在您希望将这些名称传递给 ls -l
命令以查看时间戳记。xargs 命令就是用来完成此项工作的。它允许您对输出执行其他某些命令。记住下面这个来自于第 1 部分中的语法： </font></p>
<p><font size="4" face="Arial">file -Lz * | grep ASCII | cut -d":" -f1 | xargs ls -ltr</font></p>
<p><font size="4" face="Arial">让我们来剖析这个命令字符串。第一个，file -Lz *，用于查找是符号链接或者经过压缩的文件。它将输出传递给下一个命令 grep ASCII，该命令在其中搜索 "ASCII" 字符串并产生如下所示的输出： <br>alert_DBA102.log:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ASCII English text<br>alert_DBA102.log.Z:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ASCII text (compress'd data 16 bits)<br>dba102_asmb_12307.trc.Z: ASCII English text (compress'd data 16 bits)<br>dba102_asmb_20653.trc.Z: ASCII English text (compress'd data 16 bits)</font></p>
<p><font size="4" face="Arial">由于我们只对文件名感兴趣，因此我们应用下一个命令 cut -d":" -f1，仅显示第一个字段： <br>alert_DBA102.log<br>alert_DBA102.log.Z<br>dba102_asmb_12307.trc.Z<br>dba102_asmb_20653.trc.Z</font></p>
<p><font size="4" face="Arial">现在，我们希望使用 ls -l 命令，将上述列表作为参数进行传递，一次传递一个。xargs 命令允许您这样做。最后一部分，xargs ls -ltr，用于接收输出并对其执行 ls -ltr 命令，如下所示：</font></p>
<p><font size="4" face="Arial">ls -ltr alert_DBA102.log<br>ls -ltr alert_DBA102.log.Z<br>ls -ltr dba102_asmb_12307.trc.Z<br>ls -ltr dba102_asmb_20653.trc.Z</font></p>
<p><font size="4" face="Arial">因此，xargs 本身虽然没有多大用处，但在与其他命令相结合时，它的功能非常强大。</font></p>
<p><font size="4" face="Arial">下面是另一个示例，我们希望计算这些文件中的行数：</font></p>
<p><font size="4" face="Arial">$ file * | grep ASCII | cut -d":" -f1 | xargs wc -l<br>47853 alert_DBA102.log<br>&nbsp;&nbsp;&nbsp;&nbsp; 19 dba102_cjq0_14493.trc<br>29053 dba102_mmnl_14497.trc<br>&nbsp;&nbsp;&nbsp; 154 dba102_reco_14491.trc<br>&nbsp;&nbsp;&nbsp;&nbsp; 43 dba102_rvwr_14518.trc<br>77122 total</font></p>
<p><font size="4" face="Arial">（注：上述任务还可用以下命令完成：）</font></p>
<p><font size="4" face="Arial">$ wc -l &#8216;file * | grep ASCII | cut -d":" -f1 | grep ASCII | cut -d":" -f1&#8216;</font></p>
<p><font size="4" face="Arial">该 xargs 版本用于阐释概念。Linux 可以用几种方法来完成同一个任务；请使用最适合您的情况的方法。</font></p>
<p><font size="4" face="Arial">使用该方法，您可以快速重命名目录中的文件。</font></p>
<p><font size="4" face="Arial">$ ls | xargs -t -i mv {} {}.bak</font></p>
<p><font size="4" face="Arial">-i 选项告诉 xargs 用每项的名称替换 {}。-t 选项指示 xargs 先打印命令，然后再执行。</font></p>
<p><font size="4" face="Arial">另一个非常有用的操作是当您使用 vi 打开要编辑的文件时：</font></p>
<p><font size="4" face="Arial">$ file * | grep ASCII | cut -d":" -f1 | xargs vi</font></p>
<p><font size="4" face="Arial">该命令使用 vi 逐个打开文件。当您希望搜索多个文件并打开它们进行编辑时，使用该命令非常方便。 </font></p>
<p><font size="4" face="Arial">它还有几个选项。最有用的可能是 -p 选项，它使操作具有可交互性：</font></p>
<p><font size="4" face="Arial">$ file * | grep ASCII | cut -d":" -f1 | xargs -p vi<br>vi alert_DBA102.log dba102_cjq0_14493.trc dba102_mmnl_14497.trc&nbsp;&nbsp; dba102_reco_14491.trc dba102_rvwr_14518.trc ?...</font></p>
<p><font size="4" face="Arial">此处的 xarg 要求您在运行每个命令之前进行确认。如果您按下 "y"，则执行命令。当您对文件进行某些可能有破坏且不可恢复的操作（如删除或覆盖）时，您会发现该选项非常有用。</font></p>
<p><font size="4" face="Arial">-t 选项使用一个详细模式；它显示要运行的命令，是调试过程中一个非常有帮助的选项。</font></p>
<p><font size="4" face="Arial">如果传递给 xargs 的输出为空怎么办？考虑以下命令：</font></p>
<p><font size="4" face="Arial">$ file * | grep SSSSSS | cut -d":" -f1 | xargs -t wc -l<br>wc -l <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<br>$</font></p>
<p><font size="4" face="Arial">在此处，搜索 "SSSSSS" 后没有匹配的内容；因此 xargs
的输入均为空，如第二行所示（由于我们使用 -t
这个详细选项而产生的结果）。虽然这可能会有所帮助，但在某些情况下，如果没有要处理的内容，您可能希望停止 xargs；如果是这样，可以使用 -r
选项： <br>$ file * | grep SSSSSS | cut -d":" -f1 | xargs -t -r wc -l<br>$</font></p>
<p><font size="4" face="Arial">如果没有要运行的内容，该命令退出。</font></p>
<p><font size="4" face="Arial">假设您希望使用 rm 命令（该命令将作为 xargs 命令的参数）删除文件。然而，rm 只能接受有限数量的参数。如果您的参数列表超出该限制怎么办？xargs 的 -n 选项限制单个命令行的参数个数。 </font></p>
<p><font size="4" face="Arial">下面显示了如何限制每个命令行仅使用两个参数：即使向 xargs ls -ltr 传递五个文件，但每次向 ls -ltr 仅传递两个文件。</font></p>
<p><font size="4" face="Arial">$ file * | grep ASCII | cut -d":" -f1 | xargs -t -n2 ls -ltr <br>ls -ltr alert_DBA102.log dba102_cjq0_14493.trc <br>-rw-r-----&nbsp;&nbsp;&nbsp; 1 oracle&nbsp;&nbsp; dba&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 738 Aug 10 19:18 dba102_cjq0_14493.trc<br>-rw-r--r--&nbsp;&nbsp;&nbsp; 1 oracle&nbsp;&nbsp; dba&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2410225 Aug 13 05:31 alert_DBA102.log<br>ls -ltr dba102_mmnl_14497.trc dba102_reco_14491.trc <br>-rw-r-----&nbsp;&nbsp;&nbsp; 1 oracle&nbsp;&nbsp; dba&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5386163 Aug 10 17:55 dba102_mmnl_14497.trc<br>-rw-r-----&nbsp;&nbsp;&nbsp; 1 oracle&nbsp;&nbsp; dba&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6808 Aug 13 05:21 dba102_reco_14491.trc<br>ls -ltr dba102_rvwr_14518.trc <br>-rw-r-----&nbsp;&nbsp;&nbsp; 1 oracle&nbsp;&nbsp; dba&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2087 Aug 10 04:30 dba102_rvwr_14518.trc</font></p>
<p><font size="4" face="Arial">使用该方法，您可以快速重命名目录中的文件。 </font></p>
<p><font size="4" color="#ff0000" face="Arial">$ ls | xargs -t -i mv {} {}.bak</font></p>
<p><font size="4"><font face="Arial"><font color="#ff0000">-i 选项告诉 xargs 用每项的名称替换 {}。 <br></font><br></font><br>我
需要将一个用.svn管理的项目改成由CVS来管理，因此，在导入整个项目到CVS中之前，我需要删除所有目录下以及子孙目录下的.svn目录及.svn
目录下的的子目录和文件。我一直寻找一种最简单的方法，最后写了一个程序去干这事情。结果同事告诉我只需要一条指令就可以了：</font><font size="4"><font color="#ff0000">find -name '.svn' |xargs rm -rf <br></font>这个教训非常惨重，我一生讨厌傻瓜，可那一刻发现自己是最大的傻瓜！<br><br>是的，虽然我们——至少是我，天天使用LINUX但是真的是在高效的使用这个系统吗？不，很多时候并没有花时间去研究它，使用一些固有愚蠢的方式和思维模式在使用这个系统。<br><br></font></p>
<font size="4"><strong> <font color="#ff0000">1. 建立多级目录:<br></font></strong> <br>mkidr 指令用来建立目录，事实上，我们一直都是这么干的。但是在这么使用的时候我们并没有去看它的那些参数提供了哪些额外的功能.<br><br>mkidr -p /share/dragon&nbsp;&nbsp; ; 在根目录下建立share目录，并在/share目录下建立dragon目录。</font><font size="4"><font color="#ff0000">mkdir -p guicmd/{bin,lib,src,share/version,doc/{html,pdf,info,man}}<br></font>;用来建立一个复杂的项目目录树。<br><br></font><font size="4" color="#ff0000">2.find 配合xargs使用：<br><br>find -name '.svn' |xargs rm -rf ;这个不用说了，就是我前面提到的。<br>xargs更加象一个筛选器，将符合管道传递过来的文件名的内容一并处理掉，这是一个极度高效的方法。</font>
<br><br><br>from:
http://www.cppblog.com/prayer/archive/2009/11/17/90188.html#101210<br><font size="4"><strong> <font color="#ff0000"></font></strong></font><br><img src ="http://www.cppblog.com/beautykingdom/aggbug/107949.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-02-17 04:11 <a href="http://www.cppblog.com/beautykingdom/archive/2010/02/17/107949.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 如何准确的截取出IP段</title><link>http://www.cppblog.com/beautykingdom/archive/2010/02/16/107925.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 16 Feb 2010 10:19:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/02/16/107925.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/107925.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/02/16/107925.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/107925.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/107925.html</trackback:ping><description><![CDATA[比如用到下面的命令得出了一堆信息，如何获取到本地和远端的ip呢<div><div>&nbsp;netstat -an | grep tcp</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp;0 0.0.0.0:5989 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.0.0.0:* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LISTEN</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp;0 127.0.0.1:427 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0.0.0.0:* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LISTEN</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp;0 0.0.0.0:111 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0.0.0.0:* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LISTEN</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp;0 127.0.0.1:2544 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.0.0.0:* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LISTEN</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp;0 127.0.0.1:25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.0.0.0:* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LISTEN</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp;0 :::22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :::* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LISTEN</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp;0 ::1:25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:::* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LISTEN</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; 52 192.168.2.4:22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;192.168.2.2:3107 &nbsp; &nbsp; &nbsp; &nbsp;ESTABLISHED</div><div>tcp &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp;0 192.168.2.4:22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;192.168.2.100:2184 &nbsp; &nbsp; &nbsp;ESTABLISHED</div><div>可以考虑用awk和cut的结合</div><div><div>netstat -an | grep tcp | awk '{print $5}' | cut -d: -f1</div><div>得出远端ip的信息</div><div><div>0.0.0.0</div><div>0.0.0.0</div><div>0.0.0.0</div><div>0.0.0.0</div><div>0.0.0.0</div><div><br></div><div><br></div><div>192.168.2.2</div><div>192.168.2.100</div><div>若是本地的ip信息也可以用类似的方法炮制，只是awk里的$n有点变化罢了。</div></div></div></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/107925.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-02-16 18:19 <a href="http://www.cppblog.com/beautykingdom/archive/2010/02/16/107925.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell中管道两边的进程是怎么通信的</title><link>http://www.cppblog.com/beautykingdom/archive/2010/02/13/107824.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sat, 13 Feb 2010 15:42:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/02/13/107824.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/107824.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/02/13/107824.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/107824.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/107824.html</trackback:ping><description><![CDATA[
<span style="font-family: verdana, arial, sans-serif; font-size: 13px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px; ">&nbsp;&nbsp; &nbsp; 要执行一个简单命令 shell 首先复制自身，然后 shell 等待实际上执行命令的 subshell （子shell）完成，在 subshell 中做重定向和执行 exec 系统调用，用指定程序的代码段和数据段替代 shell 代码段和数据段，进程 id 等元信息不变。&nbsp;<br>&nbsp;&nbsp; &nbsp; 管道线 a | b 执行：shell 创建一个管道，复制一个 subshell, 在其中把输出标准重定向到管道写端然后 exec a，shell 不等待这个 subshell 执行完成; shell 接着复制一个 subshell，在其中把标准输入重定向到管道读端然后 exec b, shell 等待它这个 subshell 完成。&nbsp;<br>&nbsp;&nbsp; &nbsp; 在 (...) 方式执行命令时候涉及到进一步的进程复制，shell 在复制 subshell 之后不等待其完成；subshell 在执行除了最后一个命令之外所有命令的时候都复制一个 subsubshell，在其中做重定向和 exec, subshell 在自身中重定向和 exec 最后一个命令.&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果管道由 subshell( exec a) 创建，那么subshell(exec b)就无法通过继承得到该管道描述符，从而进行重定向，那么只能使用使用named pipe了？&nbsp;</span>
<div><span style="font-family: verdana, arial, sans-serif; font-size: 13px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px; ">from：linuxforum</span></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/107824.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-02-13 23:42 <a href="http://www.cppblog.com/beautykingdom/archive/2010/02/13/107824.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GNU Linux核心命令和工具的源代码路径</title><link>http://www.cppblog.com/beautykingdom/archive/2010/01/01/104607.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 01 Jan 2010 08:09:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/01/01/104607.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/104607.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/01/01/104607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/104607.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/104607.html</trackback:ping><description><![CDATA[<p>Commands and Utilities</p>
<p>--------------------------------------------------------------------------------</p>
<p>The table below lists all of the commands and utilities set forth in chapter 17 of the Linux Standard Base specification. Also listed are the source code packages used by Architect to provide the commands as well as the primary download location for the source code. </p>
<p>command&nbsp;&nbsp; source package&nbsp; primary download site<br>--------------------------------------------------------------------------------<br>[&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>ar&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>at&nbsp;&nbsp; at&nbsp;&nbsp; <a href="http://www.happy-monkey.net/architect/src">http://www.happy-monkey.net/architect/src</a><br>awk&nbsp;&nbsp; gawk&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/gawk">ftp.gnu.org/gnu/gawk</a><br>basename&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>batch&nbsp;&nbsp; at&nbsp;&nbsp; <a href="http://www.happy-monkey.net/architect/src">http://www.happy-monkey.net/architect/src</a><br>bc&nbsp;&nbsp; bc&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/bc">ftp.gnu.org/gnu/bc</a><br>cat&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>chfn&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>chgrp&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>chmod&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>chown&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>chsh&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>cksum&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>cmp&nbsp;&nbsp; diffutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/diffutils">ftp.gnu.org/gnu/diffutils</a><br>col&nbsp;&nbsp; util-linux&nbsp; <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux">ftp.win.tue.nl/pub/linux-local/utils/util-linux</a><br>comm&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>cp&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>cpio&nbsp;&nbsp; cpio&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/cpio">ftp.gnu.org/gnu/cpio</a><br>crontab&nbsp;&nbsp; dcron&nbsp;&nbsp; <a href="ftp://ftp.ibiblio.org/pub/linux/system/daemons/cron">ftp.ibiblio.org/pub/linux/system/daemons/cron</a><br>csplit&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>cut&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>date&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>dd&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>df&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>diff&nbsp;&nbsp; diffutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/diffutils">ftp.gnu.org/gnu/diffutils</a><br>dirname&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>dmesg&nbsp;&nbsp; util-linux&nbsp; <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux">ftp.win.tue.nl/pub/linux-local/utils/util-linux</a><br>du&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>echo&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>egrep&nbsp;&nbsp; grep&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/grep">ftp.gnu.org/gnu/grep</a><br>env&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>expand&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>expr&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>false&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>fgrep&nbsp;&nbsp; grep&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/grep">ftp.gnu.org/gnu/grep</a><br>file&nbsp;&nbsp; file&nbsp;&nbsp; <a href="ftp://ftp.astron.com/pub/file">ftp.astron.com/pub/file</a><br>fold&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>fuser&nbsp;&nbsp; psmisc&nbsp;&nbsp; <a href="http://sourceforge.net/projects/psmisc">http://sourceforge.net/projects/psmisc</a><br>gencat&nbsp;&nbsp; man&nbsp;&nbsp; <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/man">ftp.win.tue.nl/pub/linux-local/utils/man</a><br>getconf&nbsp;&nbsp; glibc&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/glibc">ftp.gnu.org/gnu/glibc</a><br>gettext&nbsp;&nbsp; gettext&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/gettext">ftp.gnu.org/gnu/gettext</a><br>grep&nbsp;&nbsp; grep&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/grep">ftp.gnu.org/gnu/grep</a><br>groupadd&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>groupdel&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>groupmod&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>groups&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>gunzip&nbsp;&nbsp; gzip&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/gzip">ftp.gnu.org/gnu/gzip</a><br>gzip&nbsp;&nbsp; gzip&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/gzip">ftp.gnu.org/gnu/gzip</a><br>head&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>hostname&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>iconv&nbsp;&nbsp; glibc&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/glibc">ftp.gnu.org/gnu/glibc</a><br>id&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>install&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>install_initd&nbsp; [not implemented]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [N/A]<br>ipcrm&nbsp;&nbsp; util-linux&nbsp; <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux">ftp.win.tue.nl/pub/linux-local/utils/util-linux</a><br>join&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>kill&nbsp;&nbsp; procps&nbsp;&nbsp; <a href="http://procps.sourceforge.net/">http://procps.sourceforge.net</a><br>killall&nbsp;&nbsp; psmisc&nbsp;&nbsp; <a href="http://sourceforge.net/projects/psmisc">http://sourceforge.net/projects/psmisc</a><br>ln&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>locale&nbsp;&nbsp; glibc&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/glibc">ftp.gnu.org/gnu/glibc</a><br>localedef&nbsp; glibc&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/glibc">ftp.gnu.org/gnu/glibc</a><br>logname&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>lpr&nbsp;&nbsp; LPRng&nbsp;&nbsp; <a href="ftp://ftp.lprng.com/pub/LPRng/LPRng">ftp.lprng.com/pub/LPRng/LPRng</a><br>ls&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>lsb_release&nbsp; [not implemented] [N/A]<br>m4&nbsp;&nbsp; m4&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/m4">ftp.gnu.org/gnu/m4</a><br>make&nbsp;&nbsp; make&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/make">ftp.gnu.org/gnu/make</a><br>man&nbsp;&nbsp; man&nbsp;&nbsp; <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/man">ftp.win.tue.nl/pub/linux-local/utils/man</a><br>md5sum&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>mkdir&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>mkfifo&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>mknod&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>mktemp&nbsp;&nbsp; mktemp&nbsp;&nbsp; <a href="ftp://ftp.mktemp.org/pub/mktemp">ftp.mktemp.org/pub/mktemp</a><br>more&nbsp;&nbsp; less&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/less">ftp.gnu.org/gnu/less</a><br>mount&nbsp;&nbsp; util-linux&nbsp; <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux">ftp.win.tue.nl/pub/linux-local/utils/util-linux</a><br>msgfmt&nbsp;&nbsp; getttext&nbsp; <a href="ftp://ftp.gnu.org/gnu/gettext">ftp.gnu.org/gnu/gettext</a><br>mv&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>newgrp&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>nice&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>nl&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>nohup&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>od&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>passwd&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>paste&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>patch&nbsp;&nbsp; patch&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/patch">ftp.gnu.org/gnu/patch</a><br>pathck&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>pidof&nbsp;&nbsp; procps&nbsp;&nbsp; <a href="http://procps.sourceforge.net/">http://procps.sourceforge.net</a><br>pr&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>printf&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>ps&nbsp;&nbsp; procps&nbsp;&nbsp; <a href="http://procps.sourceforge.net/">http://procps.sourceforge.net</a><br>pwd&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>remove_initd&nbsp; [not implemented] [N/A]<br>renice&nbsp;&nbsp; util-linux&nbsp; <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux">ftp.win.tue.nl/pub/linux-local/utils/util-linux</a><br>rm&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>rmdir&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>rsync&nbsp;&nbsp; rsync&nbsp;&nbsp; <a href="ftp://ftp.samba.org/pub/rsync">ftp.samba.org/pub/rsync</a><br>sed&nbsp;&nbsp; sed&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/sed">ftp.gnu.org/gnu/sed</a><br>sendmail&nbsp; postfix&nbsp;&nbsp; <a href="ftp://ftp.porcupine.org/mirrors/postfix-release/official">ftp.porcupine.org/mirrors/postfix-release/official</a><br>sh&nbsp;&nbsp; bash&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/bash">ftp.gnu.org/gnu/bash</a><br>shutdown&nbsp; sysvinit&nbsp; <a href="ftp://ftp.cistron.nl/pub/people/miquels/sysvinit">ftp.cistron.nl/pub/people/miquels/sysvinit</a><br>sleep&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>sort&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>split&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>strip&nbsp;&nbsp; binutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/binutils">ftp.gnu.org/gnu/binutils</a><br>stty&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>su&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>sum&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>sync&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>tail&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>tar&nbsp;&nbsp; tar&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/tar">ftp.gnu.org/gnu/tar</a><br>tee&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>test&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>time&nbsp;&nbsp; time&nbsp;&nbsp; <a href="ftp://ftp.gnu.org/gnu/time">ftp.gnu.org/gnu/time</a><br>touch&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>tr&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>true&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>tsort&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>tty&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>umount&nbsp;&nbsp; util-linux&nbsp; <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux">ftp.win.tue.nl/pub/linux-local/utils/util-linux</a><br>uname&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>unexpand&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>uniq&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>useradd&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>userdel&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>usermod&nbsp;&nbsp; shadow&nbsp;&nbsp; <a href="ftp://ftp.pld-linux.org/software/shadow">ftp.pld-linux.org/software/shadow</a><br>wc&nbsp;&nbsp; coreutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/coreutils">ftp.gnu.org/gnu/coreutils</a><br>xargs&nbsp;&nbsp; findutils&nbsp; <a href="ftp://ftp.gnu.org/gnu/findutils">ftp.gnu.org/gnu/findutils</a><br>from:<br><a href="http://blog.chinaunix.net/u2/76292/showart.php?id=2135340">http://blog.chinaunix.net/u2/76292/showart.php?id=2135340</a></p>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/104607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-01-01 16:09 <a href="http://www.cppblog.com/beautykingdom/archive/2010/01/01/104607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ftp下载文件完整性校验-shell脚本</title><link>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101740.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 23 Nov 2009 13:23:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101740.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/101740.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101740.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/101740.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/101740.html</trackback:ping><description><![CDATA[<div>#!/bin/sh&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>#date=20080916&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>#echo $date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ftp -i -n&nbsp;192.168.1.161 &lt;&lt;EOF&nbsp;&nbsp; <br>user&nbsp;name&nbsp;password&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>cd bj&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ls *20080916* 20080916&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>bye&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>EOF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>aaaa=`ls *20080916* |wc -l`&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>echo $aaaa&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>bbbb=`cat&nbsp; 20080916|wc -l`&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>echo $bbbb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>if [ $aaaa -eq $bbbb ]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>then&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>echo "ftp transfered completely "<br>else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>echo "ftp transfered error"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;fi&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>#!/bin/sh&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ftp -i -n 192.168.1.152 &lt;&lt;EOF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>user&nbsp;name&nbsp;password&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ls -lt file1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>bye&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>EOF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ls -lt &gt;file2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>awk '{print $5}'file2 | while read tty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>do\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>awk 'BEGIN {...}END{name="'tty'";\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>if($5==$name)\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>printf("%s",zhengque);\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>else\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>printf("%s transfer error\n",$9);\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>printf("the size of source file is %d,the size of this file after ftp\&nbsp; <br>transferred is %d",$name,$5);\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>}\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>' file1\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>done\</div>
转自：<br><a href="http://blog.chinaunix.net/u/28584/showart.php?id=1211619">http://blog.chinaunix.net/u/28584/showart.php?id=1211619</a>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/101740.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-11-23 21:23 <a href="http://www.cppblog.com/beautykingdom/archive/2009/11/23/101740.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SED用法小结</title><link>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101738.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 23 Nov 2009 13:21:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101738.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/101738.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101738.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/101738.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/101738.html</trackback:ping><description><![CDATA[<div>
<p style="text-indent: 2em">quote.txt</p>
<p style="text-indent: 2em">The honeysuckle hand played all night long for only $90.</p>
<p style="text-indent: 2em">It was an evening of splendid music and company.</p>
<p style="text-indent: 2em">Too bad the disco floor fell through at 23:10.</p>
<p style="text-indent: 2em">The local nurse Miss P.Neave was in attendance.</p>
<p style="text-indent: 2em">显示行</p>
<p style="text-indent: 2em">$sed -n '2p' quote.txt</p>
<p style="text-indent: 2em">范围</p>
<p style="text-indent: 2em">$sed -n '1,3p' quote.txt</p>
<p style="text-indent: 2em">匹配单词</p>
<p style="text-indent: 2em">$sed -n '/The/'p quote.txt</p>
<p style="text-indent: 2em">匹配某行单词</p>
<p style="text-indent: 2em">$sed -n '4,/The/'p quote.txt</p>
<p style="text-indent: 2em">匹配元字符</p>
<p style="text-indent: 2em">$sed -n '/\$/'p quote.txt</p>
<p style="text-indent: 2em">显示整个文件</p>
<p style="text-indent: 2em">$sed -n '1,$p' quote.txt&nbsp;&nbsp;&nbsp; sed -n '1,$'p quote.txt</p>
<p style="text-indent: 2em">任意字符</p>
<p style="text-indent: 2em">$sed -n '/.*ing/'p quote.txt&nbsp; 任意字符出现一次或N次 以ing结尾</p>
<p style="text-indent: 2em">首末行</p>
<p style="text-indent: 2em">$sed -n '1p' quote.txt</p>
<p style="text-indent: 2em">$sed -n '$p' quote.txt</p>
<p style="text-indent: 2em">打印行号</p>
<p style="text-indent: 2em">$sed -n '/music/=' quote.txt</p>
<p style="text-indent: 2em">2</p>
<p style="text-indent: 2em">$sed -n -e '/music/p' -e '/music/=' quote.txt</p>
<p style="text-indent: 2em">It was an evening of splendid music and company.</p>
<p style="text-indent: 2em">2</p>
<p style="text-indent: 2em">附加文件 </p>
<p style="text-indent: 2em">!/bin/sed -f</p>
<p style="text-indent: 2em">/文件中匹配的字符/ a\</p>
<p style="text-indent: 2em">插入的字符 +x; *.sed quote.txt</p>
<p style="text-indent: 2em">删除行</p>
<p style="text-indent: 2em">$sed '1d' quote.txt 删除第一行</p>
<p style="text-indent: 2em">$sed '1,3d' quote.txt 删除1到3行</p>
<p style="text-indent: 2em">$sed '$d' quote.txt 删除最后一行</p>
<p style="text-indent: 2em">$sed '/Neave/d' quote.txt 删除带Neave的行</p>
<p style="text-indent: 2em">替换文本</p>
<p style="text-indent: 2em">$sed 's/night/NIGHT/' quote.txt&nbsp; s替换/night/NIGHT/</p>
<p style="text-indent: 2em">$sed 's/\$//' quote.txt&nbsp; $换成空格</p>
<p style="text-indent: 2em">$sed 's/The/Wow!/g' quote.txt&nbsp;&nbsp;&nbsp; g替换所有</p>
<p style="text-indent: 2em">$sed 's/splendid/SPLENDID/w sed.out' quote.txt&nbsp; w sed.out此行写入文件</p>
<p style="text-indent: 2em">$sed -n 's/nurse/"Hello" &amp;/p' quote.txt&nbsp;&nbsp; </p>
<p style="text-indent: 2em">The local "Hello" nurse Miss P.Neave was in attendance.</p>
<p style="text-indent: 2em">$sed -n 's/played/from Hockering &amp;/p' quote.txt</p>
<p style="text-indent: 2em">将sed结果写入文件命令</p>
<p style="text-indent: 2em">$sed '1,2 w filedt' quote.txt 第一二行写入文件</p>
<p style="text-indent: 2em">$sed '/Neave/ w dht' quote.txt 匹配//的写入文件</p>
<p style="text-indent: 2em">从文件中读文本</p>
<p style="text-indent: 2em">$sed '/company./r sedex.txt' quote.txt</p>
<p style="text-indent: 2em">在quote.txt的company后换行,写入sedex.txt的内容</p>
<p style="text-indent: 2em">匹配后退出</p>
<p style="text-indent: 2em">$sed '/.a.*/q' quote.txt</p>
<p style="text-indent: 2em">任意字符后跟a,再跟任意字符0次或任意次匹配:</p>
<p style="text-indent: 2em">Line 1.band&nbsp; Line 2.bad&nbsp; Liner3.was&nbsp; Line 4.was</p>
<p style="text-indent: 2em">The honeysuckle hand played all night long for only $90.</p>
<p style="text-indent: 2em">vi dos.txt</p>
<p style="text-indent: 2em">12332##DISO##45.12^M</p>
<p style="text-indent: 2em">00332##LPSO##23.11^M</p>
<p style="text-indent: 2em">01299##USPD##34.46^M</p>
<p style="text-indent: 2em">用一个空格替换所有的##,删除最前边的0,删除尾部^M</p>
<p style="text-indent: 2em">$sed 's/##*/ /g' dos.txt</p>
<p style="text-indent: 2em">$sed 's/^0*/ /g' dos.txt</p>
<p style="text-indent: 2em">$sed 's/\^M//g' dos.txt</p>
<p style="text-indent: 2em">$cat dos.txt |sed 's/##*/ /g'|sed 's/^0*/ /'|sed 's/\^M//g'</p>
<p style="text-indent: 2em">处理报文输出</p>
<p style="text-indent: 2em">Database&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Size(MB)&nbsp;&nbsp; Date Created</p>
<p style="text-indent: 2em">-------------------------------------</p>
<p style="text-indent: 2em">GOSOUTH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2244&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12/11/97</p>
<p style="text-indent: 2em">TRISUD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5632&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8/9/99</p>
<p style="text-indent: 2em">(2 rows affected)</p>
<p style="text-indent: 2em">1&gt;使用s/-*//g删除 -----------</p>
<p style="text-indent: 2em">2&gt;使用/^$/d删除空行</p>
<p style="text-indent: 2em">3&gt;使用$d删除最后一行</p>
<p style="text-indent: 2em">4&gt;使用1d删除第一行</p>
<p style="text-indent: 2em">5&gt;使用awk {print $1}打印第一列</p>
<p style="text-indent: 2em">cat sql.txt | sed 's/--*//g' | sed '/^$/d' | sed '$d' | sed '1d' | awk '{print $1}'</p>
<p style="text-indent: 2em">去除行首数字</p>
<p style="text-indent: 2em">$vi UNH.txt</p>
<p style="text-indent: 2em">12345UND SPLLFC 234344</p>
<p style="text-indent: 2em">9999999UND SKKLT 3423</p>
<p style="text-indent: 2em">1UND SPLLY 434</p>
<p style="text-indent: 2em">$sed 's/^[0-9]*//g' UND.txt</p>
<p style="text-indent: 2em">附加文本每一行末尾加上字符串'passwd'</p>
<p style="text-indent: 2em">vi ok.txt</p>
<p style="text-indent: 2em">AC456</p>
<p style="text-indent: 2em">AC492169</p>
<p style="text-indent: 2em">AC9967</p>
<p style="text-indent: 2em">AC88345</p>
<p style="text-indent: 2em">$sed 's/[0-9]*/&amp; Passwd/g' ok.txt</p>
<p style="text-indent: 2em">从sed输出中设置shell变量</p>
<p style="text-indent: 2em">$NAME="It's a go situation"</p>
<p style="text-indent: 2em">$REPLACE="GO"</p>
<p style="text-indent: 2em">$NEW_NAME='echo $NAME | sed "s/go/$REPLACE/g"'</p>
<p style="text-indent: 2em">$echo $NEW_NAME</p>
<p style="text-indent: 2em">快速一行命令</p>
<p style="text-indent: 2em">'s/\.$//g'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除以.结尾的行</p>
<p style="text-indent: 2em">'-e /abcd/d'&nbsp;&nbsp;&nbsp;&nbsp; 删除包含abcd的行</p>
<p style="text-indent: 2em">'s/[][][]*/[]/g' 删除一个以上的空格,用一个空格代替</p>
<p style="text-indent: 2em">'s/^[][]*//g'&nbsp;&nbsp;&nbsp; 删除行首空格</p>
<p style="text-indent: 2em">'s/\.[][]*/[]//g 删除.后跟2或多个空格,以一个空格代替</p>
<p style="text-indent: 2em">'s/COL\(...\)//g'删除COL和它后边的3个字母的行</p>
<p style="text-indent: 2em">'s/^\//g'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除第一个\</p>
<p style="text-indent: 2em">'s/[]/[]//g'&nbsp;&nbsp;&nbsp;&nbsp; 删除所有空格并用tab替代</p>
<p style="text-indent: 2em">'s/^[]//g'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除行首tab键</p>
<p style="text-indent: 2em">'s/[]*//g'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除所有tab键</p>
<p style="text-indent: 2em">插入文本</p>
<p style="text-indent: 2em">$echo "Mr Willis"|sed 's/Mr/&amp; Bruce/g'</p>
<p style="text-indent: 2em">删除首字符</p>
<p style="text-indent: 2em">$echo "attkla.dc"|sed 's/^./g'</p>
<p style="text-indent: 2em">删除文件扩展名</p>
<p style="text-indent: 2em">$echo "attkla.dc"|sed 's/.dc//g'</p>
<p style="text-indent: 2em">增加扩展名</p>
<p style="text-indent: 2em">$echo "attkla"|sed 's/$/.dc/g'</p>
<p style="text-indent: 2em">替换字符系列</p>
<p style="text-indent: 2em">$x="Department+payroll%Building G"</p>
<p style="text-indent: 2em">+ 换成of %换成located</p>
<p style="text-indent: 2em">$echo $x | sed 's/\+/ of /g' | sed 's/\%/ Located at /g '<br /><br />&nbsp; &nbsp; &nbsp; 直接替换<br />&nbsp; &nbsp; &nbsp; sed -i &nbsp;'s/from/to/' filename</p>
</div>
转自：<br /><a href="http://blog.chinaunix.net/u/28584/showart.php?id=1712332">http://blog.chinaunix.net/u/28584/showart.php?id=1712332</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/101738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-11-23 21:21 <a href="http://www.cppblog.com/beautykingdom/archive/2009/11/23/101738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AWK使用</title><link>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101737.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 23 Nov 2009 13:20:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101737.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/101737.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/11/23/101737.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/101737.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/101737.html</trackback:ping><description><![CDATA[<div>以前还在玩UNIX的时候就觉得里面有个命令很好用AWK,功能强大.还有SED和ED，用这三个命令就可以解决平时工作中的问题。 <br>前几天在单位做报批量处理时,要是用手工一个网点一个网点慢慢的改的话,不通宵也得搞到3、4点钟。对于我这种懒人，那是很痛苦的事，于是只得做些懒人喜欢做的事了。花了二十分钟左右，终于把SHELL的脚本写好，每次处理43个网点的报表，用时不到15秒。 <br>脚本中所用命令为： <br>find <br>awk <br>由于长时间没有写SHELL里的脚本了，花了好些时间测试，这里重温下AWK的一些常用的用法： <br>awk 用法：awk ' pattern {action} ' <br>变量名&nbsp;&nbsp; 含义 <br>ARGC&nbsp;&nbsp; 命令行变元个数 <br>ARGV&nbsp;&nbsp; 命令行变元数组 <br>FILENAME&nbsp;&nbsp;当前输入文件名 <br>FNR&nbsp;&nbsp; 当前文件中的记录号 <br>FS&nbsp;&nbsp; 输入域分隔符，默认为一个空格 <br>RS&nbsp;&nbsp; 输入记录分隔符 <br>NF&nbsp;&nbsp; 当前记录里域个数 <br>NR&nbsp;&nbsp; 到目前为止记录数 <br>OFS&nbsp;&nbsp; 输出域分隔符 <br>ORS&nbsp;&nbsp; 输出记录分隔符 <br>1、awk '/101/' file 显示文件file中包含101的匹配行。 <br>awk '/101/,/105/' file <br>awk '$1 == 5' file <br>awk '$1 == "CT"' file 注意必须带双引号 <br>awk '$1 * $2 &gt;100 ' file <br>awk '$2 &gt;5 &amp;&amp; $2&lt;=15' file <br>2、awk '{print NR,NF,$1,$NF,}' file 显示文件file的当前记录号、域数和每一行的第一个和最后一个域。 <br>awk '/101/ {print $1,$2 + 10}' file 显示文件file的匹配行的第一、二个域加10。 <br>awk '/101/ {print $1$2}' file <br>awk '/101/ {print $1 $2}' file 显示文件file的匹配行的第一、二个域，但显示时域中间没有分隔符。 <br>3、df | awk '$4&gt;1000000 ' 通过管道符获得输入，如：显示第4个域满足条件的行。 <br>4、awk -F "|" '{print $1}' file 按照新的分隔符&#8220;|&#8221;进行操作。 <br>awk 'BEGIN { FS="[: \t|]" } <br>{print $1,$2,$3}' file 通过设置输入分隔符（FS="[: \t|]"）修改输入分隔符。 <br>Sep="|" <br>awk -F $Sep '{print $1}' file 按照环境变量Sep的值做为分隔符。 <br>awk -F '[ :\t|]' '{print $1}' file 按照正则表达式的值做为分隔符，这里代表空格、:、TAB、|同时做为分隔符。 <br>awk -F '[][]' '{print $1}' file 按照正则表达式的值做为分隔符，这里代表[、] <br>5、awk -f awkfile file 通过文件awkfile的内容依次进行控制。 <br>cat awkfile <br>/101/{print "\047 Hello! \047"} --遇到匹配行以后打印 ' Hello! '.\047代表单引号。 <br>{print $1,$2} --因为没有模式控制，打印每一行的前两个域。 <br>6、awk '$1 ~ /101/ {print $1}' file 显示文件中第一个域匹配101的行（记录）。 <br>7、awk 'BEGIN { OFS="%"} <br>{print $1,$2}' file 通过设置输出分隔符（OFS="%"）修改输出格式。 <br>8、awk 'BEGIN { max=100 ;print "max=" max} BEGIN 表示在处理任意行之前进行的操作。 <br>{max=($1 &gt;max ?$1:max); print $1,"Now max is "max}' file 取得文件第一个域的最大值。 <br>（表达式1?表达式2:表达式3 相当于： <br>if (表达式1) <br>表达式2 <br>else <br>表达式3 <br>awk '{print ($1&gt;4 ? "high "$1: "low "$1)}' file <br>9、awk '$1 * $2 &gt;100 {print $1}' file 显示文件中第一个域匹配101的行（记录）。 <br>10、awk '{$1 == 'Chi' {$3 = 'China'; print}' file 找到匹配行后先将第3个域替换后再显示该行（记录）。 <br>awk '{$7 %= 3; print $7}' file 将第7域被3除，并将余数赋给第7域再打印。 <br>11、awk '/tom/ {wage=$2+$3; printf wage}' file 找到匹配行后为变量wage赋值并打印该变量。 <br>12、awk '/tom/ {count++;} <br>END {print "tom was found "count" times"}' file END表示在所有输入行处理完后进行处理。 <br>13、awk 'gsub(/\$/,"");gsub(/,/,""); cost+=$4; <br>END {print "The total is $" cost&gt;"filename"}' file gsub函数用空串替换$和,再将结果输出到filename中。 <br>1 2 3 $1,200.00 <br>1 2 3 $2,300.00 <br>1 2 3 $4,000.00 <br>awk '{gsub(/\$/,"");gsub(/,/,""); <br>if ($4&gt;1000&amp;&amp;$4&lt;2000) c1+=$4; <br>else if ($4&gt;2000&amp;&amp;$4&lt;3000) c2+=$4; <br>else if ($4&gt;3000&amp;&amp;$4&lt;4000) c3+=$4; <br>else c4+=$4; } <br>END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file <br>通过if和else if完成条件语句 <br>awk '{gsub(/\$/,"");gsub(/,/,""); <br>if ($4&gt;3000&amp;&amp;$4&lt;4000) exit; <br>else c4+=$4; } <br>END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file <br>通过exit在某条件时退出，但是仍执行END操作。 <br>awk '{gsub(/\$/,"");gsub(/,/,""); <br>if ($4&gt;3000) next; <br>else c4+=$4; } <br>END {printf "c4=[%d]\n",c4}"' file <br>通过next在某条件时跳过该行，对下一行执行操作。 <br><br>14、awk '{ print FILENAME,$0 }' file1 file2 file3&gt;fileall 把file1、file2、file3的文件内容全部写到fileall中，格式为 <br>打印文件并前置文件名。 <br>15、awk ' $1!=previous { close(previous); previous=$1 } <br>{print substr($0,index($0," ") +1)&gt;$1}' fileall 把合并后的文件重新分拆为3个文件。并与原文件一致。 <br>16、awk 'BEGIN {"date"|getline d; print d}' 通过管道把date的执行结果送给getline，并赋给变量d，然后打印。 <br>17、awk 'BEGIN {system("echo "Input your name:\\c""); getline d;print "\nYour name is",d,"\b!\n"}' <br>通过getline命令交互输入name，并显示出来。 <br>awk 'BEGIN {FS=":"; while(getline&lt; "/etc/passwd" &gt;0) { if($1~"050[0-9]_") print $1}}' <br>打印/etc/passwd文件中用户名包含050x_的用户名。 <br>18、awk '{ i=1;while(i&lt;NF) {print NF,$i;i++}}' file 通过while语句实现循环。 <br>awk '{ for(i=1;i&lt;NF;i++) {print NF,$i}}' file 通过for语句实现循环。 <br>type file|awk -F "/" ' <br>{ for(i=1;i&lt;NF;i++) <br>{ if(i==NF-1) { printf "%s",$i } <br>else { printf "%s/",$i } }}' 显示一个文件的全路径。 <br>用for和if显示日期 <br>awk 'BEGIN { <br>for(j=1;j&lt;=12;j++) <br>{ flag=0; <br>printf "\n%d月份\n",j; <br>for(i=1;i&lt;=31;i++) <br>{ <br>if (j==2&amp;&amp;i&gt;28) flag=1; <br>if ((j==4||j==6||j==9||j==11)&amp;&amp;i&gt;30) flag=1; <br>if (flag==0) {printf "%02d%02d ",j,i} <br>} <br>} <br>}' <br>19、在awk中调用系统变量必须用单引号，如果是双引号，则表示字符串 <br>Flag=abcd <br>awk '{print '$Flag'}' 结果为abcd <br>awk '{print "$Flag"}' 结果为$Flag</div>
转自：<br><a href="http://blog.chinaunix.net/u/28584/showart.php?id=1712347">http://blog.chinaunix.net/u/28584/showart.php?id=1712347</a>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/101737.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-11-23 21:20 <a href="http://www.cppblog.com/beautykingdom/archive/2009/11/23/101737.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>find命令详解&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2009/11/10/100665.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 10 Nov 2009 14:32:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/11/10/100665.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/100665.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/11/10/100665.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/100665.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/100665.html</trackback:ping><description><![CDATA[find /etc/rc.d -name '*crond' -exec file {} \;<br><br>查找/etc/rc.d目录下面所有以crond结束的文件，并使用file指令查看其属性，注意：exec和file间是一个空格，file和{}间是一个空格，file和\;之间是一个空格，\;是一个整体。<br><br>要在/usr/linux中查找所有的*.h，并在这些文件中查找&#8220;SYSCALL_VECTOR"，最后打印出所有包含"SYSCALL_VECTOR"的文件名，有以下几种方法实现<br>find /usr/linux -name "*.h" | xargs -n50 grep SYSCALL_VECTOR<br>grep SYSCALL_VECTOR /usr/linux/*.h | cut -d':' -f1 | uniq &gt; filename<br>find /usr/linux -name "*.h" -exec grep "SYSCALL_VECTOR" {} \; -print<br><br>　　我用find / -name filename| rm -rf，不成功，请问为什么不成功？<br>find / -name filename -exec rm -rf {} \;<br>find . -name filename |rm -rf试一下{} 表示你找出来的结果。<br>\; 则相当于&#8220;宪法&#8221;，没什么说头，就是这么规定的，在 -exec 后面需要一个表示该命令终结的的符号。可以在 man find 中找到***。<br>要让rm识别find的结果，如下：<br>find / -name filename |xargs rm -rf<br>之所以find . -name filename |rm -rf不通过，是因为rm命令不接受从标准输入传过来的指令<br>　　查找含特定字符串的文件<br>例如查找当前目录下含有"the string you want find..."字符串的文件：<br>$find . -type f -exec grep &#8220;the string you want find...&#8221; {} ; -print<br><br>　　从根目录开始查tmpfile，一旦查到马上删除<br>find / -name "tmpfile" -exec rm {} \;<br><br>　　find 的perm问题<br>请问一下以下命令什么意思？关键是那个数字前的-，其他都还知道<br>find -name ".*" -perm -007<br>我知道<br>find -name ".*" -perm 755<br>这个是用来查找权限位为755的隐藏文件<br>噢，对了还有，我上边的命令都省略了find的pathname参数 find默认是查找当前工作目录的吗？<br>如果我用 -ok 替代 -exec, 那么还需要加上 {} \; 吗？<br>这个已经清楚，仍然需要，因为 -ok 只是 -exec 的提示模式，它只是多了一个确认操作的步骤,刚才没有读懂那几句E文的意思 呵呵 不好意思<br>-007是指查找所有用户都可读、写、执行的文件，要小心呀~~~<br>解释解释？<br>find -name ".*" -perm -007 和 find -name ".*" -perm 777 有区别吗？<br>-007是怎么来得呢？<br>不过有一个问题<br>我用 find . -perm -100 会列出当前目录 . , 这是为什么呢？<br><br>下面引用由explover在 2002/10/01 06:15am 发表的内容：<br>-007是指查找所有用户都可读、写、执行的文件，要小心呀~~~<br>-007是查找含其它用户(不同组,非属主)可读,写,执行的文件.并不一定要同组可读写,-是指最少权限为007.<br>下面引用由一颗小白菜在 2002/10/01 10:16am 发表的内容：<br>OK了， 呵呵<br>不过有一个问题<br>我用 find . -perm -100 会列出当前目录 . , 这是为什么呢？<br>这种方法不会准确的找出目录的. -100是指权限至少是属主可运行.<br>在unix系统下,你可以拥有对目录文件的执行权你才可以进入一个目录.这便是目录文件被列出的原因.<br>find . -perm -001 -print找到往往是目录文件.<br>我的意思当然不是使用这种方法来找目录，只不过不明白其中的 -100 意义了<br>那以此类推，是不是 -010是指权限至少是owner同组可执行的吗？也就是说其实这里的010和-是分开的，-表示一个至少的意思，而且010才是真正用来描述权限位的？<br>这样子就明白了 谢谢你噢<br><br>　　将find出来的东西拷到另一个地方?<br>find *.c -exec cp '{}' /tmp ';'<br>如果有特殊文件，可以用cpio，也可以用这样的语法：<br>find dir -name filename -print | cpio -pdv newdir<br><br>　　找出磁盘中某个大小范围内的文件<br>比如要查找磁盘中大于3M的文件：<br>find . -size +3000k -exec ls -ld {} ;<br><br>　　如何用find查找某一天更改的文件？<br>可以使用这一行命令来实现：<br>A=`find ~ -print` | ls -l --full-time $A 2&gt;/dev/null | grep "Jun 27" | grep 1998<br><br>　　使用find 命令查找某个时间段的shell怎么写。比如11点到12点的。thanks<br>创建一个脚本judgetime，内容如下：<br>ls -l $*|awk '{split($8,hour,":");if((hour[1]&gt;23 || hour[1] &lt; 1)&amp;&amp;hour[1]&lt;24)print}'<br>到要查找的目录下，运行<br>find ./ -name "*" -exec judgetime {} \;<br>注意时间格式为２４小时制。<br>thank you ，如果我要精确到分钟呢<br>touch -t 04241112 starttemp #精确到12分钟<br>touch -t 04241220 endtemp #截止到12点20<br>find [dir] -newer starttemp -a ! -newer endtemp -exec ls -l {} \;<br>ｎｅｗｅｒ？<br>那昨天１２：１０文件如何呢？<br>每天执行的时候，用当天的日期和时间戳替换一下不就行了吗？<br>我不知道他是不是把所有的11：00~12：00的都找出来，是不是只执行一次还是每天都执行？<br>这种情况俺猜想是自己的东西放在哪忘了，只记得当时是深夜了。<br>有道理！<br>不愧是斑竹！<br>不光知道怎么解决问题，还知道在什么情况下出现这类问题，佩服佩服！<br>问题又出现了。创建这个文件的时候。本来应该是时间的一栏现在写上了2002，而不是12：00.<br>等到12：00过了吧！<br><br>　　删除指定日期的文件<br>find ./ -name 文件名 -exec rm -f {} \;<br>例：删除当前30天内没用过的文件,用如下命令：<br>find / -atime +30 -exec rm -f {} \;<br>我自己试着写了一小段SHELL,也用ll ,grep, rm 几个命令，用起来还差强人意。<br>对过滤出来的文件名列表中用了一个FOR语句，再执行rm 。现在我想把这段SHELL 扩展一下让它每天定时运行将 n 天前的文件删掉，有没有人能给我一些提示，谢谢！<br>还有个问题，对于前面那位朋友提到的"find / -atime +30 -exec rm -f {} \;<br>"方法，我很早就试过几次，不过好像都不太对，参数 -atime n 是查找n天前被访问过的文件，我不明白的是这里的时间参照点是什么，以及这个n天是怎么计算的。<br>问题二、对于"ll |cut -f 1" 这个命令我是不是用错了，我只想取出 ll 中列出的文件名，但用cut -f 命令做不到 ，我只好换用 ll |cut -c 59- 这种方式得到我要的文件名，but it's a pool idear ！我也试过用awk ，好像也不对，看看大家可不可以给我一些小小的提醒，TKS SO MUCH<br>问题三、如何改变 I结点 的日期格式 我现在的系统显示的格式是：<br>-rw-r----- 1 msahz01 users 2253 2002年2月 2日 poheader.i<br>我想把这换成<br>-rw-rw-rw- 1 house users 2193 Apr 19 2001 hkdisp.p<br>如何才能做到这点？<br>awk 应该可以<br>ll | awk '{print $9}'<br>　　删除多少天之前的文件<br>find /yourpath -mtime +31 -exec rm {} \;<br>find /yourpath -mtime +366 -exec rm {} \;<br><br>find中, -ctime, -mtime及其-atime有何区别<br><br>请问 -ctime 和 -mtime 有什么关系 ?<br>如果父目录的 ctime 改变, 那它下面的文件的 ctime 就会自动都改了吗 ?<br>-ctime 和 -mtime ,-atime 这些信息是存在哪儿呢 ?<br><br>我用 -mtime -1 找到了新建或改的文件.<br>但怎样才能找到一天内 mv 来的文件呢( 它们的时间是原有的时间,早于一天 ) ?<br><br>用-newer选项啊。<br>你可以先touch一个你想要的时间的文件如下：<br>$ touch -t 08190800 test<br>$ ls -l test<br>-rw-r--r-- 1 dba other 0 Aug 19 08:00 test<br>然后<br>$ find . -newer test -print<br>.<br>./.sh_history<br>$ ls -l .sh_history<br>-rw------- 1 dba other 154 Aug 20 17:39 .sh_history<br><br>用touch可以写出你想要的任何时间的文件，然后用-newer ,! -newer选项即可成功。<br><br>1.ctime含inode信息修改的时间.mtime只指文件内容建立或修改的时间.<br>2 不会.<br>3.这些信息应该是存在文件系统的超级块里.<br><br>我查了书 -ctime 是指 inode 的改变(或称文件的状态改变).<br>请问 inode 存了哪些信息 ?<br>做了些小测试,-mtime 改, -ctime 一定也改.<br>改文件名, -ctime 也会改.<br>谁能回答 i-node 存了哪些东西 ?<br><br>vi /usr/include/sys/inode.h<br><br>班主,我不能 access /usr/include/sys/inode.h .<br>摘书如下:<br>Directories contain directory entries. Each entry contains a file or subdirectory name and an index node reference number (i-node number). To increase speed and enhance use of disk space, the data in a file is stored at various locations in the computer's memory. The i-node contains the addresses used to locate all the scattered blocks of data associated with a file. The i-node also records other information about the file including time of modification and access, access modes, number of links, file owner, and file type.<br>可我发现 -atime 改了, -ctime 还没改. why ?<br>( 我先 cat 一个 ASCII 文件,再用 -atime -1 有它用 -ctime -1 居然没有它.)<br>着岂不跟 inode 信息改变, ctime 就改矛盾吗?<br><br>我不同意你贴出来的那段文章,正如我提到的那样,atime,ctime,mtime是放到超级块里,在sco unix下是一种叫stat的结构.(stat_32),不同的系统文件系统可能不同.<br>sco 下inode的结构如下:<br><br>typedef struct inode<br>{<br>struct inode *i_forw; /* inode hash chain */<br>struct inode *i_back; /* '' */<br>struct inode *av_forw; /* freelist chain */<br>struct inode *av_back; /* '' */<br>int *i_fsptr; /* "typeless" pointer to fs dependent */<br>ino32_t i_number; /* i number, 1-to-1 with dev address */<br>ushort i_ftype; /* file type = IFDIR, IFREG, etc. */<br>short i_fstyp; /* File system type */<br>off_t i_size; /* size of file */<br>ushort i_uid; /* owner */<br>ushort i_gid; /* group of owner */<br>ushort i_flag;<br>ushort i_want; /* i_flag extension to avoid MP races */<br>ushort i_count; /* reference count */<br>short i_nlink; /* directory entries */<br>dev_t i_rdev; /* Raw device number */<br>#define i_namtype i_rdev /* i_ftype==IFNAM subtype */<br>dev_t i_dev; /* device where inode resides */<br>struct mount *i_mton;/* ptr to mount table entry that */<br>/* this directory is mounted on */<br>struct region *i_rp; /* ptr to shared region if any */<br>struct stdata *i_sp; /* ptr to associated stream */<br>struct iisem *isem; /* ptr to XENIX semaphores */<br>struct iisd *isd; /* ptr to XENIX shared data */<br>} i_un;<br>#define i_mnton i_un.i_mton /* i_ftype==IFDIR IMOUNT */<br>#define i_rptr i_un.i_rp /* i_ftype==IFREG || i_ftype==IFBLK */<br>#define i_sptr i_un.i_sp /* i_ftype==IFCHR || i_ftype==IFIFO */<br>#define i_sem i_un.isem /* i_ftype==IFNAM &amp;&amp; i_namtype==IFSEM */<br>#define i_sd i_un.isd /* i_ftype==IFNAM &amp;&amp; i_namtype==IFSHD */<br><br>struct fstypsw *i_fstypp; /* ptr to file system switch FSPTR */<br>long *i_filocks; /* pointer to filock (structure) list */<br>unsigned long i_mappages; /* number of pages currently cached */<br>unsigned long i_vcode; /* read-ahead block save (NFS) */<br>short i_wcnt; /* write open count or ITEXT count */<br>struct lockb i_cilock; /* tas to synchronize i_flag changes */<br>ushort i_rdlocks; /* count of non-exclusive lockers */<br>} inode_t;<br><br><br>所以,访问一个文件不能改变inode信息.<br>使用chown, chgrp, chmod命令可以很好的比较mtime和ctime<br>chown改变一个文件的属主,用ctime可以找到,用mtime便找不到.<br>试试看.<br><br>多谢斑竹! 我是在 Solaris 上面试的.我是对 -ctime 不明白.<br>试的结果如下:<br>修改文件,-mtime 改了, -ctime 也会改.<br>访问文件,-atime 改了, -ctime 没变.<br>chown, chgrp, chmod,mv, 都会使 -ctime 改变,但不影响 -atime 和 -mtime.<br>touch 可以改 -mtime and/or -atime,但 touch -a 只改访问时间时,-ctime也改了.<br>touch -m 改修改时间时,-ctime当然也改了.<br>好象还有别的很多东西可以令 -ctime 改变, 搞不清楚.<br>有什么方法可以显示 -mtime,atime,ctime 吗?<br>可以用 -ctime 来实现对目录的增量文件进行备份或 transfer 吗 ?<br>多谢!<br><br>没有什么工具显示,(可能是俺不知道)<br>把下面程序里的st_mtime换成st_ctime,或st_atime便可以得到你要的了.<br>＃i nclude<br>int<br>main (int argc, char **argv)<br>{<br>struct stat buf;<br>char date[80];<br>char fname[80];<br>printf("Enter filename (with full path) to check mtime : ");<br>scanf("%s",fname);<br>stat(fname, &amp;buf);<br>printf ("mtime (in sec) of %s = %ld\n", fname, buf.st_mtime);<br>strcpy(date, ctime((time_t *)&amp;(buf.st_mtime)));<br>printf ("mtime (in date) of %s = %s\n", fname, date);<br>}<br><br>至于文件备份,有什么不可以的么?<br><br>mtime ls -l 最近修改文件内容的时间<br>atime ls -lu 最近访问文件的时间<br>ctime ls -li 最近文件有所改变的状态 ,如文件修改,属性\属主 改变 ,节点 ,链接变化等 ,应该是不拘泥只是时间前后的改变<br><br>俺看了ls的帮助,以为只是按ctime或atime排序,显示的时间还是mtime.<br><br>仔细比较了一下,ayhan说的是对的.谢谢ayhan.<br><br>多谢 ahyan 提示 ! 我在 Solaris 上试过如下:<br>mtime 用 ls -l 看到<br>atime 用 ls -lu 看到<br>ctime 用 ls -lc 看到. (ls -li 只有 inode number)<br>摘书如下:<br>-c Uses time of last modification of the i-node (file<br>created, mode changed, and so forth) for sorting (-t)<br>or printing (-l or -n).<br>-u Uses time of last access instead of last modification<br>for sorting (with the -t option) or printing (with the<br>-l option).<br>-i For each file, prints the i-node number in the first<br>column of the report.<br><br>我在sco unix5.0.5中试了一下，好像不对：chmod,chgrp等不会改变ls -il显示的时间；vi,touch倒是有影响。<br>每一种操作系统都是由成千上万个不同种类的文件所组成的。其中有系统本身自带的文件，用户自己的文件，还有共享文件等等。我们有时候经常忘记某份文件放在硬盘中的哪个地方。在微软的WINDOWS操作系统中要查找一份文件是相当简单的事情， 只要在桌面上点击&#8220;开始&#8221;－&#8220;搜索&#8221;中就能按照各种方式在本地硬盘上，局域网络，甚至在INTERNET上查找各种文件，文档。<br>　　可是使用linux的用户就没有那么幸运了，在Linux上查找某个文件确实是一件比较麻烦的事情。毕竟在linux中需要我们使用专用的&#8220;查找&#8221;命令来寻找在硬盘上的文件。Linux 下的文件表达格式非常复杂，不象WINDOWS,DOS下都是统一的AAAAAAA.BBB格式那么方便查找，在WINDOWS中，只要知道要查找的文件的文件名或者后缀就非常容易查找到。linux中查找文件的命令通常为&#8220;find&#8221;命令，&#8220;find&#8221;命令能帮助我们在使用,管理linux的日常事务中方便的查找出我们需要的文件。对于linux新手来说，&#8220;find&#8221;命令也是了解和学习Linux 文件特点的方法。因为linux发行版本繁多，版本升级很快，在Linux书籍上往往写明某个配置文件的所在位置，往往linux新手按图索骥还是不能找到。比如说REDHAT Linux 7.O 和REDHAT linux 7.1中有些重要的配置文件所在的硬盘位置和文件目录就有了很大的改变，如果不学会使用&#8220;find&#8221;命令，那么在成千上万的linux文件中要找到其中的一个配置文件是相当困难的，笔者在没有精通&#8220;find&#8221;命令之前就吃过这样的苦头。好，下面就详细为大家介绍强大的&#8220;find&#8221;命令的全部使用方法和用途。<br><br>通过文件名查找法：<br>　　这个方法说起来就和在WINDOWS下查找文件一样容易理解了。 如果你把这个文件放在单个的文件夹里面，只要使用常见的&#8220;ls"命令就能方便的查找出来，那么使用&#8220;find&#8221;命令来查找它就不能给你留下深刻的印象，毕竟&#8220;find&#8221;命令的强大功能不止这个。如果知道了某个文件的文件名，而不知道这个文件放到哪个文件夹，甚至是层层套嵌的文件夹里。举例说明，假设你忘记了httpd.conf这个文件在系统的哪个目录下，甚至在系统的某个地方也不知道，则这是可以使用如下命令：<br>　　find / -name httpd.conf<br>　　这个命令语法看起来很容易就明白了，就是直接在find后面写上 -name，表明要求系统按照文件名查找，最后写上httpd.conf这个目标文件名即可。稍等一会系统会在计算机屏幕上显示出查找结果列表：<br>　　etc/httpd/conf/httpd.conf<br>　　这就是httpd.conf这个文件在linux系统中的完整路径。查找成功。<br>　　如果输入以上查找命令后系统并没有显示出结果，那么不要以为系统没有执行 find/ -name httpd.conf命令，而可能是你的系统中没有安装Apache服务器，这时只要你安装了Apache Web服务器，然后再使用find / -name httpd.conf就能找到这个配置文件了。<br><br>无错误查找技巧：<br>　　在linux系统中&#8220;find&#8221;命令是大多数系统用户都可以使用的命令， 并不是ROOT系统管理员的专利。但是普通用户使用&#8220;find&#8221;命令时也有可能遇到这样的问题，那就是L inux系统中系统管理员ROOT可以把某些文件目录设置成禁止访问模式。这样普通用户就没有权限用&#8220;find&#8221;命令来查询这些目录或者文件。当普通用户使用&#8220;find&#8221;命令来查询这些文件目录是，往往会出现"Permissiondenied."（禁止访问）字样。 系统将无法查询到你想要的文件。为了避免这样的错误，我们可是使用转移错误提示的方法尝试着查找文件，输入<br>　　find / -name access_log 2&gt;/dev/null<br>　　这个方法是把查找错误提示转移到特定的目录中去。系统执行这个命令后，遇到错误的信息就直接输送到stderrstream 2 中，access_log 2 就是表明系统将把错误信息输送到stderrstream 2中，/dev/null是一个特殊的文件，表明空的或者错误的信息，这样查询到的错误信息将被转移了，不会再显示了。<br><br>　　在linux系统查找文件也会遇到这样一个实际问题。如果我们在整个硬盘， 这个系统中查找某个文件就要花费相当长的一段时间，特别是大型linux系统和容量较大的硬盘，文件放在套嵌很深的目录中的时候。如果我们知道了这个文件存放在某个大的目录中，那么只要在这个目录中往下找就能节省很多时间了。使用find /etc -name httpd.conf 就可以解决这个问题。上面的命令就是表示在etc目录中查询httpd.conf这个文件。 这里再说明一下&#8220;/ &#8221;这个函数符号的含义，如果输入 &#8220;find/ &#8221;就是表示要求linux系统在整个 ROOT目录下查找文件，也就是在整个硬盘上查找文件，而&#8220;find/etc&#8221;就是只在 etc目录下查找文件。因为&#8220;find/etc&#8221;表示只在etc目录下查找文件， 所以查找的速度就相应要快很多了。<br><br>根据部分文件名查找方法：<br>　　这个方法和在WINDOWS中查找已知的文件名方法是一样的。不过在linux中根据部分文件名查找文件的方法要比在WINDOWS中的同类查找方法要强大得多。 例如我们知道某个文件包含有srm这3个字母，那么要找到系统中所有包含有这3个字母的文件是可以实现的，输入：<br>　　find /etc -name '*srm*'<br>　　这个命令表明了linux系统将在/etc 整个目录中查找所有的包含有srm这3个字母的文件，比如 absrmyz，tibc.srm等等符合条件的文件都能显示出来。如果你还知道这个文件是由 srm 这3个字母打头的，那么我们还可以省略最前面的星号，命令如下：<br>　　find/etc -name 'srm*'<br>　　这是只有像srmyz 这样的文件才被查找出来，象absrmyz或者absrm这样的文件都不符合要求，不被显示，这样查找文件的效率和可靠性就大大增强了。<br><br>根据文件的特征查询方法：<br>　　如果只知道某个文件的大小，修改日期等特征也可以使用"find"命令查找出来，这和 WINDOWS系统中的"搜索"功能是基本相同的。在微软的"搜索"中WINDOWS中的"搜索助理"使得搜索文件和文件夹、打印机、用户以及网络中的其他计算机更加容易。它甚至使在 Internet 上搜索更加容易。"搜索助理"还包括一个索引服务， 该服务维护了计算机中所有文件的索引，使得搜索速度更快。使用"搜索助理"时，用户可以指定多个搜索标准。例如，用户可以按名称、类型及大小搜索文件和文件夹。用户甚至可以搜索包含特定文本的文件。如果用户正使用 Active Directory，这时还可以搜索带有特定名称或位置的打印机。<br>　　例如我们知道一个linux文件大小为1,500 bytes，那么我们可是使用如下命令来查询 find / -size 1500c，字符 c 表明这个要查找的文件的大小是以bytes为单位。如果我们连这个文件的具体大小都不知道，那么在linux中还可以进行模糊查找方式来解决。 例如我们输入find/ -size +10000000c 这个命令， 则标明我们指定系统在根目录中查找出大于10000000字节的文件并显示出来。命令中的&#8220;＋&#8221;是表示要求系统只列出大于指定大小的文件，而使用&#8220;-&#8221;则表示要求系统列出小于指定大小的文件。下面的列表就是在linux使用不同"find"命令后系统所要作出的查找动作， 从中我们很容易看出在linux中使用"find" 命令的方式是很多的，"find"命令查找文件只要灵活应用， 丝毫不必在WINDOWS中查找能力差。<br>　　find / -amin -10 # 查找在系统中最后10分钟访问的文件<br>　　find / -atime -2 # 查找在系统中最后48小时访问的文件<br>　　find / -empty # 查找在系统中为空的文件或者文件夹<br>　　find / -group cat # 查找在系统中属于 groupcat的文件<br>　　find / -mmin -5 # 查找在系统中最后5分钟里修改过的文件<br>　　find / -mtime -1 #查找在系统中最后24小时里修改过的文件<br>　　find / -nouser #查找在系统中属于作废用户的文件<br>　　find / -user fred #查找在系统中属于FRED这个用户的文件<br>　　下面的列表就是对find命令所可以指定文件的特征进行查找的部分条件。在这里并没有列举所有的查找条件，参考有关linux有关书籍可以知道所有find命令的查找函数。<br>-amin n<br>查找系统中最后N分钟访问的文件<br>-atime n<br>查找系统中最后n*24小时访问的文件<br>-cmin n<br>查找系统中最后N分钟被改变状态的文件<br>-ctime n<br>查找系统中最后n*24小时被改变状态的文件<br>-empty<br>查找系统中空白的文件，或空白的文件目录，或目录中没有子目录的文件夹<br>-false<br>查找系统中总是错误的文件<br>-fstype type<br>查找系统中存在于指定文件系统的文件，例如：ext2<br>-gid n<br>查找系统中文件数字组 ID 为 n的文件<br>-group gname<br>查找系统中文件属于gnam文件组，并且指定组和ID的文件<br><br><br>Find命令的控制选项说明：<br>Find命令也提供给用户一些特有的选项来控制查找操作。下表就是我们总结出的最基本，最常用的find命令的控制选项及其用法。<br>选项<br>用途描述<br>-daystart<br>.测试系统从今天开始24小时以内的文件，用法类似-amin<br>-depth<br>使用深度级别的查找过程方式,在某层指定目录中优先查找文件内容<br>-follow<br>遵循通配符链接方式查找; 另外，也可忽略通配符链接方式查询<br>-help<br>显示命令摘要<br>-maxdepth levels<br>在某个层次的目录中按照递减方法查找<br>-mount<br>不在文件系统目录中查找， 用法类似 -xdev.<br>-noleaf<br>禁止在非UNUX文件系统，MS-DOS系统，CD-ROM文件系统中进行最优化查找<br>-version<br>打印版本数字<br><br>使用-follow选项后，find命令则遵循通配符链接方式进行查找，除非你指定这个选项，否则一般情况下find命令将忽略通配符链接方式进行文件查找。<br><br>-maxdepth选项的作用就是限制find命令在目录中按照递减方式查找文件的时候搜索文件超过某个级别或者搜索过多的目录，这样导致查找速度变慢，查找花费的时间过多。例如，我们要在当前(.)目录技巧子目录中查找一个名叫fred的文件，我们可以使用如下命令<br>find . -maxdepth 2 -name fred<br><br>假如这个fred文件在./sub1/fred目录中，那么这个命令就会直接定位这个文件，查找很容易成功。假如，这个文件在. /sub1/sub2/fred目录中，那么这个命令就无法查找到。因为前面已经给find命令在目录中最大的查询目录级别为2，只能查找2层目录下的文件。这样做的目的就是为了让find命令更加精确的定位文件，如果你已经知道了某个文件大概所在的文件目录级数，那么加入-maxdepth n 就很快的能在指定目录中查找成功。<br><br>使用混合查找方式查找文件<br>find命令可以使用混合查找的方法，例如我们想在/tmp目录中查找大于100000000字节并且在48小时内修改的某个文件，我们可以使用-and 来把两个查找选项链接起来组合成一个混合的查找方式。<br>find /tmp -size +10000000c -and -mtime +2<br><br>学习过计算机语言的朋友都知道，在计算机语言里，使用and ,or 分别表示&#8220;与&#8221;和&#8220;或&#8221;的关系。在linux系统的查找命令中一样通用。<br>还有这样的例子，<br>find / -user fred -or -user george<br><br>我们可以解释为在/tmp目录中查找属于fred或者george这两个用户的文件。<br>在find命令中还可以使用&#8220;非&#8221;的关系来查找文件，如果我们要在/tmp目录中查找所有不属于panda的文件，使用一个简单的<br>find /tmp ! -user panda<br>命令就可以解决了。很简单。<br><br>查找并显示文件的方法<br>查找到某个文件是我们的目的，我们更想知道查找到的文件的详细信息和属性，如果我们采取现查找文件，在使用LS命令来查看文件信息是相当繁琐的，现在我们也可以把这两个命令结合起来使用。<br>find / -name "httpd.conf" -ls<br><br>系统查找到httpd.conf文件后立即在屏幕上显示httpd.conf文件信息。<br>12063 34 -rw-r--r-- 1 root root 33545 Dec 30 15:36 /etc/httpd/conf/httpd.conf<br><br>下面的表格就是一些常用的查找文件并显示文件信息的参数和使用方法<br>选项<br>用途描述<br>-exec command;<br>查找并执行命令<br>-fprint file<br>打印文件完整文件名<br>-fprint0 file<br>打印文件完整文件名包括空的文件<br>-fprintf file format<br>打印文件格式<br>-ok command;<br>给用户命令执行操作，根据用户的Y 确认输入执行<br>-printf format<br>打印文件格式<br>-ls<br>打印同种文件格式的文件<br><br>总结：到这里为止我们已经学习了这名多关于find命令的使用方法，也列出了很多常用的find命令的选项，如果我们能熟练掌握在linux中find命令的使用方法，那么在Linux中查找文件也不是一件困难的事情。<br><br>转自：<br><a href="http://www.lupaworld.com/94908/viewspace-109380.html">http://www.lupaworld.com/94908/viewspace-109380.html</a> 
<img src ="http://www.cppblog.com/beautykingdom/aggbug/100665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-11-10 22:32 <a href="http://www.cppblog.com/beautykingdom/archive/2009/11/10/100665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux shell 小片段</title><link>http://www.cppblog.com/beautykingdom/archive/2009/11/08/100395.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 08 Nov 2009 03:19:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/11/08/100395.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/100395.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/11/08/100395.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/100395.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/100395.html</trackback:ping><description><![CDATA[1.<span style="color: #000000; font-size: 16px;">关于文件对比的Scripts<br>diff -b -r $Dir1 $Dir2 | grep -v "Common subdirectories" |&nbsp;grep -e "^diff" -e "^Binary files" -e "^Only"<br>diff:<br>&nbsp;-b&nbsp; --ignore-space-change&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;Ignore changes in the amount of white space.<br>&nbsp;-r&nbsp; --recursive<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Recursively compare any subdirectories found.<br>grep:<br>&nbsp;-v, --invert-match<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Invert the sense of matching, to select non-matching lines.<br>&nbsp;-e PATTERN, --regexp=PATTERN<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Use PATTERN as the pattern; useful to protect patterns beginning with -.<br><br>2. grep的正则表达式：<br>比如,要匹配两个单詞:&nbsp;&nbsp;word&nbsp;&nbsp;exec<br>grep -E "word|execl"&nbsp;&nbsp;是可以得到正确结果的<br>AND:<br>grep -E "word&amp;execl"&nbsp;&nbsp;和预期的不一样<br>grep -E 'excel.*word|work.*excel'是可以的。<br>注：正则表达式跟逻辑操作符是俩概念 ， 只有awk支持||，&amp;&amp;这样的操作， <br>用grep的话， 也只支持|而不支持&amp;。<br>正则基础：)<br>$cat rfile<br>abcd<br>abc<br>ab<br><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#98;&#101;&#97;&#117;&#116;&#121;&#64;&#108;&#105;&#110;&#117;&#120;&#45;&#103;&#122;&#110;&#112;&#58;&#126;&#47;&#99;&#111;&#100;&#101;&#47;&#115;&#104;&#101;&#108;&#108;&#47;&#116;&#101;&#115;&#116;">$</a>grep -E 'abc.*' rfile<br>abcd<br>abc<br><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#98;&#101;&#97;&#117;&#116;&#121;&#64;&#108;&#105;&#110;&#117;&#120;&#45;&#103;&#122;&#110;&#112;&#58;&#126;&#47;&#99;&#111;&#100;&#101;&#47;&#115;&#104;&#101;&#108;&#108;&#47;&#116;&#101;&#115;&#116;">$</a>grep -E 'abc*' rfile<br>abcd<br>abc<br>ab<br><br>3. <span style="color: #000000; font-size: 16px;">如何获得一个文件的前N列或是其中的几列？</span><br>cut -f-2 -d ' ' filename<br>-f field&nbsp;&nbsp; -d dilimeter<br><br>4.删除某个目录下不是以.sh .h .c结尾的文件<br></span>find . -type f | awk '!/\.sh$/ &amp;&amp; !/\.[c|h]$/{print $1}' | xargs rm
<br><span style="color: #000000; font-size: 16px;"><br>5.原来用冒号分隔的，选出几列来，改成用竖杠分隔的<br>cat /etc/passwd | awk -F: '{print $1"|"$2"|"$3"|"$4}'<br><br>6.去掉文件中的字符，比如去掉从win上传到Linux上的文件时会有个^M,若去掉他可以用：<br></span>tr -d '\015'&nbsp; &lt; filename<br><span style="color: #000000; font-size: 16px;"><br>7.目录树是<br>A/B/C/<br>A/B/C/ccc/...<br>A/B/C/bbb/...<br>A/B/C/D/aaa/...<br>我现在在A下，我要查找html后缀文件， 但是不想它在包含aaa||bbb||ccc的目录下查找.<br>find . \( -name Input -o -name Output -o -name Current \) -type d -prune -o -name "*.htm" -print<br>这个命令中的目录排除没有起作用，为什么嗯？很困惑。<br>find . -wholename './A/B' -prune -o -print<br>这个命令也不起作用，更困惑了，不认wholename<br><br></span>8. 循环读文件的命令
<br>for x in `seq 1 12`; do cat $x|awk '{print $9}' &amp;&amp; sleep
3;done
<br>
<div>seq 是Linux 中一個預設的外部命令,一般用作一堆數字的簡化寫法，如<br>seq 1 10<br>便會出現 <br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10
<br>它還有三個選項<br>&nbsp; -f, --format=FORMAT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; use printf style
floating-point FORMAT (default: %g)<br>&nbsp; -s, --separator=STRING&nbsp;&nbsp; use
STRING to separate numbers (default: \n)<br>&nbsp; -w, --equal-width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
equalize width by padding with leading zeroes</div>
<div>-f 最常用 , 例如一次制做 10 個名 dir001 , dir002 .. dir010 的目錄，它便很有用途,我們可以這樣</div>
<div>下一個命令便可了<br>seq -f 'dir%03g' 1 10 | xargs mkdir<br>或<br>mkdir $(seq
-f 'dir%03g' 1 10)<br>它用的是 printf 的格式 , %03g' 代表以三位浮點數,以此方法，</div>
<div>如用bash3 的 printf也可作為等價命令<br>printf 'dir%03d\n' {1..10} | xargs
mkdir&nbsp; 或 mkdir `printf 'dir%03d ' {1..10}`</div>
<div>awk 當然也可以<br>awk 'BEGIN { while (num &lt; 10 ) printf "dir%03d\n",
++num ; exit}' | xargs mkdir</div>
<div>這樣會比寫一個腳本快, 不必寫成<br>for dir in 001 002 003 004 005 006 007 008 009
010<br>do<br>&nbsp;&nbsp;&nbsp; mkdir dir${dir}<br>done<br><br>9.找出当前目录下大于100M的目录<br>find . -maxdepth 1 -type d | xargs du -sh | grep -v '\.$'| grep -P '^\S+M\t' | awk -FM '$1&gt;1'<br></div>
<br>       <img src ="http://www.cppblog.com/beautykingdom/aggbug/100395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-11-08 11:19 <a href="http://www.cppblog.com/beautykingdom/archive/2009/11/08/100395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 下 scp 的用法&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2009/11/02/99965.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 02 Nov 2009 02:25:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/11/02/99965.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/99965.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/11/02/99965.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/99965.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/99965.html</trackback:ping><description><![CDATA[ copy 本地的档案到远程的机器上 
scp /etc/lilo.conf k@net67.ee.oit.edu.tw:/home/k 
会将本地的 /etc/lilo.conf 这个档案 copy 到 net67.ee.oit.edu.tw，使用者 k 的家目录下。 
copy远程机器上的档案到本地来 
scp k@net67.ee.oit.edu.tw:/etc/lilo.conf /etc 
会将 net67.ee.oitdu.tw 中 /etc/lilo.conf 档案 copy 到本地的 /etc 目录下。 
保持从来源 host 档案的属性 
scp &#8211;p k@net67.ee.tw:/etc/lilo.conf /etc 

如果想使用特定端口 使用 scp &#8211;p（大写） 如 scp &#8211;p 1234 k@net67.ee.tw:/etc/lilo.conf /etc 


在此必须注意使用者的权限是否可读取远程上的档案，若想知道更多关于 scp 的使用方法，可去看看 scp 的使用手册。 
ssh-keygen 
产生公开钥 (pulib key) 和私人钥 (private key)，以保障 ssh 联机的安性， 当 ssh 连 shd 服务器，会交换公开钥上，系统会检查 /etc/ssh_know_hosts 内储存的 key，如果找到客户端就用这个 key 产生一个随机产生的session key 传给服务器，两端都用这个 key 来继续完成 ssh 剩下来的阶段。 

它会产生 identity.pub、identity 两个档案，私人钥存放于identity，公开钥 存放于 identity.pub 中，接下来使用 scp 将 identity.pub copy 到远程机器的家目录下.ssh下的authorized_keys。 .ssh/authorized_keys(这个 authorized_keys 档案相当于协议的 rhosts 档案)， 之后使用者能够不用密码去登入。RSA的认证绝对是比 rhosts 认证更来的安全可靠。 
执行： 
scp identity.pub k@linux1.ee.oit.edu.tw:.ssh/authorized_keys 

若在使用 ssh-keygen 产生钥匙对时没有输入密码，则如上所示不需输入密码即可从 net67.ee.oit.edu.tw 去登入 linux1.ee.oit.edu.tw。在此，这里输入的密码可以跟帐号的密码不同，也可以不输入密码。

转自:
http://www.cnblogs.com/gergro/archive/2008/06/19/1225959.html<img src ="http://www.cppblog.com/beautykingdom/aggbug/99965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-11-02 10:25 <a href="http://www.cppblog.com/beautykingdom/archive/2009/11/02/99965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BASH 中的字符串处理</title><link>http://www.cppblog.com/beautykingdom/archive/2009/10/05/97893.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 05 Oct 2009 10:07:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/10/05/97893.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/97893.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/10/05/97893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/97893.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/97893.html</trackback:ping><description><![CDATA[得到长度<br><br>
<div class=msgbody>
<div class=msgheader>
<div class=right><a class=smalltxt onclick="copycode($('code0'));" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[Copy to clipboard]</font></u></a> <a class=smalltxt onclick="toggle_collapse('code0');" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[ <span id=code0_symbol>-</span> ]</font></u></a></div>
CODE:</div>
<div id=code0 class=msgborder &nbsp;&nbsp;style="font-family:Fixdays">%x="abcd"<br>#方法一<br>%expr length $x<br>4<br># 方法二<br>%echo ${#x}<br>4<br># 方法三<br>%expr "$x" : ".*"<br>4<br># expr 的帮助<br># STRING : REGEXP&nbsp; &nbsp;anchored pattern match of REGEXP in STRING</div>
</div>
<br>查找子串<br><br>
<div class=msgbody>
<div class=msgheader>
<div class=right><a class=smalltxt onclick="copycode($('code1'));" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[Copy to clipboard]</font></u></a> <a class=smalltxt onclick="toggle_collapse('code1');" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[ <span id=code1_symbol>-</span> ]</font></u></a></div>
CODE:</div>
<div id=code1 class=msgborder &nbsp;&nbsp;style="font-family:Fixdays">%expr index&nbsp;&nbsp;$x "b"<br>2<br>%expr index&nbsp;&nbsp;$x "a"<br>1<br>%expr index&nbsp;&nbsp;$x "b"<br>2<br>%expr index&nbsp;&nbsp;$x "c"<br>3<br>%expr index&nbsp;&nbsp;$x "d"<br>4</div>
</div>
<br>得到子字符串<br><br>
<div class=msgbody>
<div class=msgheader>
<div class=right><a class=smalltxt onclick="copycode($('code2'));" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[Copy to clipboard]</font></u></a> <a class=smalltxt onclick="toggle_collapse('code2');" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[ <span id=code2_symbol>-</span> ]</font></u></a></div>
CODE:</div>
<div id=code2 class=msgborder &nbsp;&nbsp;style="font-family:Fixdays"># 方法一<br># expr &lt;string&gt; startpos length<br>%expr substr "$x" 1 3<br>abc<br>%expr substr "$x" 1 5<br>abcd<br>%expr substr "$x" 2 5<br>bcd<br># 方法二<br># ${x:pos:lenght}<br>%echo ${x:1}<br>bcd<br>%echo ${x:2}<br>cd<br>%echo ${x:0}<br>abcd<br>%echo ${x:0:2}<br>ab<br>%pos=1<br>%len=2<br>%echo ${x:$pos:$len}<br>bc</div>
</div>
<br>匹配正则表达式<br><br>
<div class=msgbody>
<div class=msgheader>
<div class=right><a class=smalltxt onclick="copycode($('code3'));" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[Copy to clipboard]</font></u></a> <a class=smalltxt onclick="toggle_collapse('code3');" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[ <span id=code3_symbol>-</span> ]</font></u></a></div>
CODE:</div>
<div id=code3 class=msgborder &nbsp;&nbsp;style="font-family:Fixdays"># 打印匹配长度<br>%expr match $x "."<br>1<br>%expr match $x "abc"<br>3<br>%expr match $x "bc"<br>0</div>
</div>
<br>字符串的掐头去尾<br><br>
<div class=msgbody>
<div class=msgheader>
<div class=right><a class=smalltxt onclick="copycode($('code4'));" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[Copy to clipboard]</font></u></a> <a class=smalltxt onclick="toggle_collapse('code4');" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[ <span id=code4_symbol>-</span> ]</font></u></a></div>
CODE:</div>
<div id=code4 class=msgborder &nbsp;&nbsp;style="font-family:Fixdays">%x=aabbaarealwwvvww<br>%echo "${x%w*w}"<br>aabbaarealwwvv<br>%echo "${x%%w*w}"<br>aabbaareal<br>%echo "${x##a*a}"<br>lwwvvww<br>%echo "${x#a*a}"<br>bbaarealwwvvww</div>
</div>
<br>其中 , # 表示掐头， 因为键盘上 # 在 $ 的左面。<br>其中 , % 表示%，&nbsp;&nbsp;因为键盘上 % 在 $ 的右面。<br>单个的表示最小匹配，双个表示最大匹配。<br>也就是说，当匹配的有多种方案的时候，选择匹配的最大长度还是最小长度。<br><br>字符串的替换<br><br>
<div class=msgbody>
<div class=msgheader>
<div class=right><a class=smalltxt onclick="copycode($('code5'));" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[Copy to clipboard]</font></u></a> <a class=smalltxt onclick="toggle_collapse('code5');" href="http://bbs.chinaunix.net/viewthread.php?tid=201843###"><u><font color=#0000ff>[ <span id=code5_symbol>-</span> ]</font></u></a></div>
CODE:</div>
<div id=code5 class=msgborder &nbsp;&nbsp;style="font-family:Fixdays">%x=abcdabcd<br>%echo ${x/a/b} # 只替换一个<br>bbcdabcd<br>%echo ${x//a/b} # 替换所有<br>bbcdbbcd</div>
</div>
<br>不可以使用 regexp ， 只能用 * ? 的文件扩展方式。<br><br>转自：<br><a href="http://bbs.chinaunix.net/viewthread.php?tid=201843">http://bbs.chinaunix.net/viewthread.php?tid=201843</a><br>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/97893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-10-05 18:07 <a href="http://www.cppblog.com/beautykingdom/archive/2009/10/05/97893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell解释器问题--命令不听话 </title><link>http://www.cppblog.com/beautykingdom/archive/2009/10/05/97877.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 05 Oct 2009 03:05:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/10/05/97877.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/97877.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/10/05/97877.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/97877.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/97877.html</trackback:ping><description><![CDATA[经常会遇到一些问题就是为什么命令不是安你想要的执行!!!!举个例子你<br>&nbsp; find /usr -type f -name string* <br>&nbsp; 你本意你想找string.c .h阿.什么之类的.就是*是当通配符了.可是如果你的当前路径有个string.c文件的话,你就知道问题了。<br><br>[root@mip-123456 string]# ls<br>[root@mip-123456 string]# find /usr/src/linux-2.6.18/arch/ -type f -name string*<br>/usr/src/linux-2.6.18/arch/ppc/lib/string.S<br>/usr/src/linux-2.6.18/arch/ppc/boot/common/string.S<br>/usr/src/linux-2.6.18/arch/m68k/lib/string.c<br>/usr/src/linux-2.6.18/arch/cris/arch-v10/lib/string.c<br>/usr/src/linux-2.6.18/arch/cris/arch-v32/lib/string.c<br>/usr/src/linux-2.6.18/arch/s390/lib/string.c<br>/usr/src/linux-2.6.18/arch/powerpc/lib/string.S<br>/usr/src/linux-2.6.18/arch/powerpc/boot/string.h<br>/usr/src/linux-2.6.18/arch/powerpc/boot/string.S<br>[root@mip-123456 string]# touch string.h<br>[root@mip-123456 string]# find /usr/src/linux-2.6.18/arch/ -type f -name string*<br>/usr/src/linux-2.6.18/arch/powerpc/boot/string.h<br>[root@mip-123456 string]# find /usr/src/linux-2.6.18/arch/ -type f -name "string*"<br>/usr/src/linux-2.6.18/arch/ppc/lib/string.S<br>/usr/src/linux-2.6.18/arch/ppc/boot/common/string.S<br>/usr/src/linux-2.6.18/arch/m68k/lib/string.c<br>/usr/src/linux-2.6.18/arch/cris/arch-v10/lib/string.c<br>/usr/src/linux-2.6.18/arch/cris/arch-v32/lib/string.c<br>/usr/src/linux-2.6.18/arch/s390/lib/string.c<br>/usr/src/linux-2.6.18/arch/powerpc/lib/string.S<br>/usr/src/linux-2.6.18/arch/powerpc/boot/string.h<br>/usr/src/linux-2.6.18/arch/powerpc/boot/string.S<br>聪明的你已经看出问题了。<br><br>由于[0-9]这种匹配模式是出现在命令的 argument位置上,所以由shell负责解释(所以严格而言, [0-9]是通配符,而不是正则表达式)。对shell而言,统配符只对文件名有效,也就是说,当shell遇到出现在某个命令行的argument位置上的通配符时,它先要去参数所指定的目录下搜索所有已经存在的文件,所有文件名字与之匹配的都要替换到argument位置上(这与很多标准的命令支持多个文件名参数是一致的),然后调用该命令执行.
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; 对于mkdir ./dir[0-9]而言,shell无法在当前目录下找到与之匹配的文件名,所以就不替换,dir[0-9]按照原样传给mkdir程序,所以mkdir就建立了一个名字为dir[0-9]的目录. </div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; 总之一句话,通配符(出现在argument位置)由shell负责解释(与现有的文件名匹配),与具体的命令(ls,rm,mkdir)无关.正则表达式(出现在option位置上)由具体的应用程序解释(grep,sed,awk),与shell无关。</div>
<div>&nbsp;</div>
<div>一个试验的例子是: <br>&nbsp;&nbsp;&nbsp; 如果当前目录下已经有一个名为dir5的目录,执行 mkdir ./dir[0-9]后,出现错误提示:mkdir: cannot create directory `./dir5': File exists 这就证明了,因为存在dir5,所以shell匹配到了dir5,所以真正执行的是mkdir ./dir5</div>
<div><br><font color=#0000ff>seq -f 'dir%01g' 0 9 | xargs mkdir&nbsp; <br>[victor@localhost tmp]$ ls <br>[victor@localhost tmp]$ seq -f 'dir%01g' 0 9 | xargs mkdir <br>[victor@localhost tmp]$ ls <br>dir0&nbsp; dir1&nbsp; dir2&nbsp; dir3&nbsp; dir4&nbsp; dir5&nbsp; dir6&nbsp; dir7&nbsp; dir8&nbsp; dir9 </font></div>
<div>&nbsp;</div>
<div>seq 是Linux 中一個預設的外部命令,一般用作一堆數字的簡化寫法，如<br>seq 1 10<br>便會出現 <br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10 <br>它還有三個選項<br>&nbsp; -f, --format=FORMAT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; use printf style floating-point FORMAT (default: %g)<br>&nbsp; -s, --separator=STRING&nbsp;&nbsp; use STRING to separate numbers (default: \n)<br>&nbsp; -w, --equal-width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equalize width by padding with leading zeroes</div>
<div>-f 最常用 , 例如一次制做 10 個名 dir001 , dir002 .. dir010 的目錄，它便很有用途,我們可以這樣</div>
<div>下一個命令便可了<br>seq -f 'dir%03g' 1 10 | xargs mkdir<br>或<br>mkdir $(seq -f 'dir%03g' 1 10)<br>它用的是 printf 的格式 , %03g' 代表以三位浮點數,以此方法，</div>
<div>如用bash3 的 printf也可作為等價命令<br>printf 'dir%03d\n' {1..10} | xargs mkdir&nbsp; 或 mkdir `printf 'dir%03d ' {1..10}`</div>
<div>awk 當然也可以<br>awk 'BEGIN { while (num &lt; 10 ) printf "dir%03d\n", ++num ; exit}' | xargs mkdir</div>
<div>這樣會比寫一個腳本快, 不必寫成<br>for dir in 001 002 003 004 005 006 007 008 009 010<br>do<br>&nbsp;&nbsp;&nbsp; mkdir dir${dir}<br>done</div>
转自：<br><a href="http://blog.chinaunix.net/u2/76292/showart_1931660.html">http://blog.chinaunix.net/u2/76292/showart_1931660.html</a><br><br><br>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/97877.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-10-05 11:05 <a href="http://www.cppblog.com/beautykingdom/archive/2009/10/05/97877.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>date命令使用</title><link>http://www.cppblog.com/beautykingdom/archive/2009/06/19/88132.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 19 Jun 2009 15:17:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/06/19/88132.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/88132.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/06/19/88132.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/88132.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/88132.html</trackback:ping><description><![CDATA[1.设置时间<br>&nbsp;&nbsp; (1)可以用date 061923122009，即月日时分年<br>&nbsp;&nbsp; (2)要是想使用更详细的设置，可以用date -s '2009-06-19 23:09:00',这样可以设置到秒。
<img src ="http://www.cppblog.com/beautykingdom/aggbug/88132.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-06-19 23:17 <a href="http://www.cppblog.com/beautykingdom/archive/2009/06/19/88132.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell十三问&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2009/06/02/86507.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 02 Jun 2009 01:03:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/06/02/86507.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/86507.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/06/02/86507.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/86507.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/86507.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自：http://blog.csdn.net/chinalinuxzend/archive/2007/10/16/1826623.aspxshell 十三问：1) 为何叫做 shell ？ 2) shell prompt(PS1) 与 Carriage Return(CR) 的关系？ 3) 别人 echo、你也 echo ，是问 echo 知多少？ 4) " "(双引号) 与 ' '(单引号)差...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2009/06/02/86507.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/86507.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-06-02 09:03 <a href="http://www.cppblog.com/beautykingdom/archive/2009/06/02/86507.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux Shell Learning Notes ---- String</title><link>http://www.cppblog.com/beautykingdom/archive/2009/06/01/86393.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 01 Jun 2009 06:08:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/06/01/86393.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/86393.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/06/01/86393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/86393.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/86393.html</trackback:ping><description><![CDATA[转自：<br><a href="http://hi.baidu.com/wangyuquansky/blog/item/46863716e253e756f2de322a.html">http://hi.baidu.com/wangyuquansky/blog/item/46863716e253e756f2de322a.html</a><br><br>1.字符串的操作：<br>&nbsp;&nbsp; 1.1&nbsp;<font color=#ff0000>字符串的类型<br></font>&nbsp;/ 数字或者数字组合（能够返回结果，即程序退出状态是0，说明属于这种类型，反之不然）<br>$ i=5;j=9423483247234;<br>$ echo $i | grep [0-9]*<br>5<br>$ echo $j | grep [0-9]*<br>9423483247234<br>$ echo $j | grep [0-9]* &gt;/dev/null<br>$ echo $?<br>0<br>// 字符组合（小写字母、大写字母、两者的组合）<br>$ c="A"; d="fwefewjuew"; e="fewfEFWefwefe"<br>$ echo $c | grep [A-Z]<br>A<br>$ echo $d | grep "[a-z]*"<br>fwefewjuew<br>$ echo $e | grep "[a-zA-Z]*"<br>fewfEFWefwefe<br>// 字母和数字的组合<br>$ ic="432fwfwefeFWEwefwef"<br>$ echo $ic | grep "[0-9a-zA-Z]*"<br>432fwfwefeFWEwefwef<br>// 空格或者Tab键等<br>$ echo " " | grep " "<br><br>$ echo -e "\t" | grep "[[:space:]]" #[[:space:]]会同时匹配空格和TAB键<br><br>$ echo -e " \t" | grep "[[:space:]]"<br><br>$ echo -e "\t" | grep "&lt;tab&gt;" #&lt;tab&gt;为在键盘上按下TAB键，而不是字符&lt;tab&gt;<br>// 匹配邮件地址<br>$ echo "test2007@lzu.cn" | grep "[0-9a-zA-Z\.]*@[0-9a-zA-Z\.]"<br>test2007@lzu.cn<br>// 匹配URL地址(以http链接为例）<br>$ echo "http://news.lzu.edu.cn/article.jsp?newsid=10135" | grep "http://[0-9a-zA-Z\./=?]*"<br><a href="http://news.lzu.edu.cn/article.jsp?newsid=10135" target=_blank><font color=#000000><u>http://news.lzu.edu.cn/article.jsp?newsid=10135</u></font></a><br><br>说明：<br>[1] /dev/null和/dev/zero是非常有趣的两个设备，它们都犹如一个黑洞，什么东西掉进去都会消失殆尽；后者则是一个能源箱，你总能从那里取到0，直到你退出。两者的部分用法见：<a href="http://oss.lzu.edu.cn/modules/newbb/viewtopic.php?topic_id=686&amp;forum=6&amp;post_id=2842#forumpost2842" target=_blank><font color=#000000><u>关于zero及NULL设备的一些问题</u></font></a><br>[2] [[:space:]]是grep用于匹配空格或者TAB键类型字符串的一种标记，其他类似的标记请查看grep的帮助,man grep。<br>[3] 上面都是用grep来进行模式匹配，实际上sed, awk都可以用来做模式匹配，关于匹配中用到的正则匹配模式知识，大家可以参考<a href="http://x.discuz.net/180642/viewspace-19070" target=_blank><font color=#000000><u>正则匹配模式</u></font></a>，更多相关资料请看参考资料。<br>[4] 如果仅仅想判断字符串是否为空，即判断字符串的长度是否为零，那么可以简单的通过test命令的-z选项来判断，具体用法见test命令，man test.<br><br>概要示例: 判断字符是否可打印？如何控制字符在终端的显示。<br><br>
<table style="BORDER-BOTTOM: rgb(153,153,187) 1px solid; BORDER-TOP: rgb(153,153,187) 1px solid" class=FCK__ShowTableBorders border=0 cellSpacing=2 cellPadding=1 width="100%" align=center>
    <tbody>
        <tr>
            <td bgColor=#dfefef>
            <p style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 3px; MARGIN-LEFT: 5px">// 用grep判断某个字符是否为可打印字符<br>$ echo "\t\n" | grep "[[:print:]]"<br>\t\n<br>$ echo $?<br>0<br>$ echo -e "\t\n" | grep "[[:print:]]"<br>$ echo $?<br>1<br>// 用echo的-e选项在屏幕控制字符显示位置、颜色、背景等<br>$ echo -e "\33[31;40m" #设置前景色为黑色，背景色为红色<br>$ echo -e "\33[11;29H Hello, World\!" #在屏幕的第11行，29列开始打印字符串Hello,World!<br>// 在屏幕的某个位置动态显示当前系统时间<br>$ while :; do echo -e "\33[11;29H "$(date "+%Y-%m-%d %H:%M:%S"); done<br>// 用col命令过滤掉某些控制字符，在处理诸如script,screen等截屏命令的输出结果时，很有用<br>$ screen -L<br>$ cat /bin/cat<br>$ exit<br>$ cat screenlog.0 | col -b&nbsp;&nbsp; # 把一些控制字符过滤后，就可以保留可读的操作日志</p>
            </td>
        </tr>
    </tbody>
</table>
<br><br>更多关于字符在终端的显示控制方法，请参考资料[20]和字符显示实例[21]：用shell实现的一个动态时钟。<br><br>1.2&nbsp; <font color=#ff0000>字符串的长度</font><br><br>概要示例: 除了组成字符串的字符类型外，字符串还有哪些属性呢？组成字符串的字符个数。下面我们来计算字符串的长度，即所有字符的个数，并简单介绍几种求字符串中指定字符个数的方法。<br><br>
<table style="BORDER-BOTTOM: rgb(153,153,187) 1px solid; BORDER-TOP: rgb(153,153,187) 1px solid" class=FCK__ShowTableBorders border=0 cellSpacing=2 cellPadding=1 width="100%" align=center>
    <tbody>
        <tr>
            <td bgColor=#dfefef><font color=#000000>
            <p style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 3px; MARGIN-LEFT: 5px">// 计算某个字符串的长度，即所有字符的个数[这计算方法是五花八门，择其优着而用之]<br>$ var="get the length of me"<br>$ echo ${var}&nbsp;&nbsp;&nbsp;&nbsp; # 这里等同于$var<br>get the length of me<br>$ echo ${#var}<br>20<br>$ expr length "$var"<br>20<br>$ echo $var | awk '{printf("%d\n", length($0));}'<br>20<br>$ echo -n $var | wc -c<br>20<br>// 计算某些指定一个字符或者多个字符的个数<br>$ echo $var | tr -cd g | wc -c<br>2<br>$ echo -n $var | sed -e 's/[^g]//g' | wc -c<br>2<br>$ echo -n $var | sed -e 's/[^gt]//g' | wc -c<br>5<br>// 如果要统计单词个数，更多相关信息见《shell编程之数值计算》之 _单词统计_ 实例。<br>$ echo $var | wc -w<br>5<br>$ echo "$var" | tr " " "\n" | grep get | uniq -c<br>1<br>$ echo "$var" | tr " " "\n" | grep get | wc -l<br>1</p>
            </font></td>
        </tr>
    </tbody>
</table>
<br><br>说明：<br>${}操作符在Bash里头一个&#8220;大牛&#8221;，能胜任相当多的工作，具体就看看网中人的《shell十三问》之《Shell十三问》之"$(( )) 與 $( ) 還有${ } 差在哪？" 吧。<br><br><font color=#ff0000>1.3 字符串的存储<br><br></font>在我们看来，字符串是一连串的字符而已，但是为了操作方便，我们往往可以让字符串呈现出一定的结构。在这里，我们不关心字符串在内存中的实际存储结构，仅仅关系它呈现出来的逻辑结构。比如，这样一个字符串："get the length of me"，我们可以从不同的方面来呈现它。<br><br><font color=#ff0000>1.3.1</font> 通过字符在串中的位置来呈现它<br><br>这样我们就可以通过指定位置来找到某个子串。这在c语言里头通常可以利用指针来做。而在shell编程中，有很多可用的工具，诸如expr，awk都提供了类似的方法来实现子串的查询动作。两者都几乎支持模式匹配(match)和完全匹配(index)。这在后面的字符串操作中将详细介绍。<br><br><font color=#ff0000>1.3.2</font> 根据某个分割符来取得字符串的各个部分<br><br>这里最常见的就是行分割符、空格或者TAB分割符了，前者用来当行号，我们似乎已经司空见惯了，因为我们的编辑器就这样&#8220;莫名&#8221;地处理着行分割符（在 unix下为\n，在其他系统下有一些不同，比如windows下为\r\n)。而空格或者TAB键经常用来分割数据库的各个字段，这似乎也是司空见惯的事情。<br><br>正是因为这样，所以产生了大量优秀的行编辑工具，诸如grep,awk,sed等。在&#8220;行内&#8221;（姑且这么说吧，就是处理单行，即字符串里头不再包含行分割符）的字符串分割方面，cut和awk提供了非常优越的&#8220;行内&#8221;（处理单行）处理能力。<br><br><font color=#ff0000>1.3.3</font> 更方便地处理用分割符分割好的各个部分<br><br>同样是用到分割符，但为了更方便的操作分割以后的字符串的各个部分，我们抽象了&#8220;数组&#8221;这么一个数据结构，从而让我们更加方便地通过下标来获取某个指定的部分。bash提供了这么一种数据结构，而优秀的awk也同样提供了它，我们这里将简单介绍它们的用法。<br><br>概要示例：利用数组存放"get the length of me"的用空格分开的各个部分。<br><br>
<table style="BORDER-BOTTOM: rgb(153,153,187) 1px solid; BORDER-TOP: rgb(153,153,187) 1px solid" class=FCK__ShowTableBorders border=0 cellSpacing=2 cellPadding=1 width="100%" align=center>
    <tbody>
        <tr>
            <td bgColor=#dfefef>
            <p style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 3px; MARGIN-LEFT: 5px">//1. bash提供的数组数据结构，它是以数字为下标的，和C语言从0开始的下标一样<br>$ var="get the length of me"<br>$ var_arr=($var)&nbsp;&nbsp; #这里把字符串var存放到字符串数组var_arr中了，默认以空格作为分割符<br>$ echo ${var_arr[0]} ${var_arr[1]} ${var_arr[2]} ${var_arr[3]} ${var_arr[4]}<br>get the length of me<br>$ echo ${var_arr[@]}&nbsp;&nbsp; #这个就是整个字符串所有部分啦，这里可以用*代替@，下同<br>get the length of me<br>$ echo ${#var_arr[@]}&nbsp;&nbsp; #记得上面求某个字符串的长度么，#操作符，如果想求某个数组元素的字符串长度，那么就把@换成下标吧<br>5<br>// 你也可以直接给某个数组元素赋值<br>$ var_arr[5]="new_element"<br>$ echo ${var_arr[5]}<br>6<br>$ echo ${var_arr[5]}<br>new_element<br>// bash里头实际上还提供了一种类似于&#8220;数组&#8221;的功能，即"for i in 用指定分割符分开的字符串" 的用法<br>// 即，你可以很方便的获取某个字符串的某个部分<br>$ for i in $var; do echo -n $i" "; done;<br>get the length of me <br><br>//2. awk里头的数组，注意比较它和bash提供的数组的异同<br>// split把一行按照空格分割，存放到数组var_arr中，并返回数组的长度。注意：这里的第一个元素下标不是0，而是1<br>$ echo $var | awk '{printf("%d %s\n", split($0, var_arr, " "), var_arr[1]);}' <br>5 get<br>// 实际上，上面的操作很类似awk自身的行处理功能：awk默认把一行按照空格分割为多个域，并可以通过$1,$2,$3...来获取,$0表示整行<br>// 这里的NF是该行的域的总数，类似于上面数组的长度，它同样提供了一种通过&#8220;下标&#8221;访问某个字符串的功能<br>$ echo $var | awk '{printf("%d | %s %s %s %s %s | %s\n", NF, $1, $2, $3, $4, $5, $0);}'<br>5 | get the length of me | get the length of me<br>// awk的&#8220;数组&#8221;功能何止于此呢，看看它的for引用吧，注意，这个和bash里头的for不太一样，i不是元素本身，而是下标<br>$ echo $var | awk '{split($0, var_arr, " "); for(i in var_arr) printf("%s ",var_arr<em>);}'<br>get the length of me <br>$ echo $var | awk '{split($0, var_arr, " "); for(i in var_arr) printf("%s ",i);}'<br>1 2 3 4 5 <br>// awk还有更&#8220;厉害&#8221;的处理能力，它的下标可以不是数字，而可以是字符串，从而变成了&#8220;关联&#8221;数组，这种&#8220;关联&#8221;的作用在某些方便将让我们非常方便<br>// 比如，我们这里就实现一个非凡的应用，把某个文件中的某个系统调用名替换成地址，如果你真正用起它，你会感慨它的&#8220;鬼斧神工&#8221;的。<br>// 这就是我在一个场合最好才发现的随好的实现方案：有兴趣看看<a href="http://oss.lzu.edu.cn/modules/newbb/viewtopic.php?topic_id=1006&amp;forum=26&amp;post_id=3954#forumpost3954" target=_blank><font color=#000000><u>awk手册</u></font></a>帖子中我在3楼回复的实例吧。<br>$ cat symbol <br>sys_exit<br>sys_read<br>sys_close<br>$ ls /boot/System.map*<br>$ awk '{if(FILENAME ~ "System.map") map[$3]=$1; else {printf("%s\n", map[$1])}}' /boot/System.map-2.6.20-16-generic symbol <br>c0129a80<br>c0177310<br>c0175d80<br>// 另外，awk还支持删除某个数组元素，如果你不用了就可以用delete函数给删除掉。如果某些场合有需要的话，别忘了awk还支持二维数组。<br></em></p>
            </td>
        </tr>
    </tbody>
</table>
<br><br>okay，就介绍到这里啦。为什么要介绍这些内容？再接着看下面的内容，你就会发现，那些有些的工具是怎么产生和发展起来的了，如果累了，看看最后一篇参考资料吧，它介绍了一些linux命令名字的由来，说不定可以帮助你理解本节下面的部分呢。<br><br><font color=#ff0000>2. 字符串常规操作<br><br></font>字符串操作包括取子串、查询子串、插入子串、删除子串、子串替换、子串比较、子串排序、子串进制转换、子串编码转换等。<br><br><font color=#ff0000>2.1 取子串</font><br><br>概要示例：取子串的方法主要有：直接到指定位置求子串，字符匹配求子串。<br><br>
<table style="BORDER-BOTTOM: rgb(153,153,187) 1px solid; BORDER-TOP: rgb(153,153,187) 1px solid" class=FCK__ShowTableBorders border=0 cellSpacing=2 cellPadding=1 width="100%" align=center>
    <tbody>
        <tr>
            <td bgColor=#dfefef><font color=#000000>
            <p style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 3px; MARGIN-LEFT: 5px">// 按照位置取子串，比如从什么位置开始，取多少个字符<br>$ var="get the length of me"<br>$ echo ${var:0:3}<br>get<br>$ echo ${var:(-2)}&nbsp;&nbsp; # 方向相反呢<br>me<br>$ echo `expr substr "$var" 5 3` #记得把$var引起来，否则expr会因为空格而解析错误<br>the<br>$ echo $var | awk '{printf("%s\n", substr($0, 9, 6))}'<br>length<br><br>// 匹配字符求子串<br>$ echo ${var%% *} #从右边开始计算，删除最左边的空格右边的所有字符<br>get <br>$ echo ${var% *} #从右边开始计算，删除第一个空格右边的所有字符<br>get the length of<br>$ echo ${var##* } #从左边开始计算，删除最右边的空格左边的所有字符<br>me<br>$ echo ${var#* } #从左边开始计算，删除第一个空格左边的所有字符<br>the length of me<br><br>$ echo $var | awk '{printf("%s\n", $1);}' # awk把$var按照空格分开为多个变量，依次为$1,$2,$3,$4,$5<br>get<br>$ echo $var | awk '{printf("%s\n", $5);}'<br>me<br><br>$ echo $var | cut -d" " -f 5 #差点把cut这个小东西忘记啦，用起来和awk类似, -d指定分割符，如同awk用-F指定分割符一样，-f指定&#8220;域&#8221;，如同awk的$数字。<br><br>$ echo $var | sed 's/ [a-z]*//g' #删除所有 空格＋字母串 的字符串，所以get后面的全部被删除了<br>get<br>$ echo $var | sed 's/[a-z]* //g'<br>me<br><br>$ echo $var | tr " " "\n" | sed -n 1p #sed有按地址（行）打印(p)的功能，记得先用tr把空格换成行号<br>get<br>$ echo $var | tr " " "\n" | sed -n 5p<br>me<br><br>// tr也可以用来取子串哦，它也可以类似#和%来&#8220;拿掉&#8221;一些字符串来实现取子串<br>$ echo $var | tr -d " "<br>getthelengthofme<br>$ echo $var | tr -cd "[a-z]" #把所有的空格都拿掉了，仅仅保留字母字符串，注意-c和-d的用法<br>getthelengthofme</p>
            </font></td>
        </tr>
    </tbody>
</table>
<br><br>说明：<br>[1] %和#的区别是，删除字符的方向不一样,前者在右，后者在左，%%和%,##和#的方向是前者是最大匹配，后者是最小匹配。(好的记忆方法见网中人的键盘记忆法:#$%是键盘依次从左到右的三个键)<br>[2] tr的-c选项是complement的缩写，即invert，而-d选项是删除的意思，tr -cd "[a-z]"这样一来就变成保留所有的字母啦。<br><br>对于字符串的截取，实际上还有一些命令，如果head,tail等可以实现有意思的功能，可以截取某个字符串的前面、后面指定的行数或者字节数。例如：<br><br>
<table style="BORDER-BOTTOM: rgb(153,153,187) 1px solid; BORDER-TOP: rgb(153,153,187) 1px solid" class=FCK__ShowTableBorders border=0 cellSpacing=2 cellPadding=1 width="100%" align=center>
    <tbody>
        <tr>
            <td bgColor=#dfefef><font color=#000000>
            <p style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 3px; MARGIN-LEFT: 5px">$ echo "abcdefghijk" | head -c 4<br>abcd<br>$ echo -n "abcdefghijk" | tail -c 4<br>hijk</p>
            </font></td>
        </tr>
    </tbody>
</table>
<br><br><font color=#ff0000>2.2. 查询子串</font><br><br>概要示例：子串查询包括：返回符合某个模式的子串本身和返回子串在目标串中的位置。<br><br>准备：在进行下面的操作之前，请把<a href="http://oss.lzu.edu.cn/blog/blog.php?do_showone/tid_1385.html" target=_blank><font color=#000000><u>http://oss.lzu.edu.cn/blog/blog.php?do_showone/tid_1385.html</u></font></a>链接中的内容复制到一个文本text里头，用于下面的操作。<br><br>
<table style="BORDER-BOTTOM: rgb(153,153,187) 1px solid; BORDER-TOP: rgb(153,153,187) 1px solid" class=FCK__ShowTableBorders border=0 cellSpacing=2 cellPadding=1 width="100%" align=center>
    <tbody>
        <tr>
            <td bgColor=#dfefef>
            <p style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 3px; MARGIN-LEFT: 5px">// 查询子串在目标串中的位置<br>$ var="get the length of me"<br>$ expr index "$var" t&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #貌似仅仅可以返回某个字符或者多个字符中第一个字符出现的位置<br>3 <br>$ echo $var | awk '{printf("%d\n", match($0,"the"));}'&nbsp;&nbsp; #awk却能找出字串,match还可以匹配正则表达式<br>5 <br><br>// 查询子串，返回包含子串的行(awk,sed都可以实现这些功能,但是grep最擅长）<br>$ grep "consists of" text&nbsp;&nbsp; # 查询text文件包含consists of的行，并打印这些行<br>$ grep "consists[[:space:]]of" -n -H text # 打印文件名，子串所在行的行号和该行的内容<br>$ grep "consists[[:space:]]of" -n -o text # 仅仅打印行号和匹配到的子串本身的内容<br>$ awk '/consists of/{ printf("%s:%d:%s\n",FILENAME, FNR, $0)}' text #看到没？和grep的结果一样<br>$ sed -n -e '/consists of/=;/consists of/p' text #同样可以打印行号</p>
            </td>
        </tr>
    </tbody>
</table>
<br><br>说明：<br>[1] awk,grep,sed都能通过模式匹配查找指定的字符串，但是它们各有擅长的领域，我们将在后续的章节中继续使用和比较它们，从而发现各自的优点。<br>[2] 在这里我们姑且把文件内容当成了一个大的字符串，在后面的章节中我们将专门介绍文件的操作，所以对文件内容中存放字符串的操作将会有更深入的分析和介绍。<br><br><font color=#ff0000>2.3. 子串替换</font><br><br>子串替换就是把某个指定的子串替换成其他的字符串，实际上这里就蕴含了&#8220;插入子串&#8221;和&#8220;删除子串&#8221;的操作。例如，你想插入某个字符串到某个子串之前，就可以把原来的子串替换成&#8221;子串+新的字符串&#8220;，如果想删除某个子串，就把子串替换成空串。不过有些工具提供了一些专门的用法来做插入子串和删除子串的操作，所以呆伙还是会专门介绍的。另外，要想替换掉某个子串，一般都是先找到子串（查询子串），然后再把它替换掉的，实质上很多工具在使用和设计上都体现了这么一点。<br><br>概要示例：下面我们把变量var中的空格替换成下划线看看。<br><br>
<table style="BORDER-BOTTOM: rgb(153,153,187) 1px solid; BORDER-TOP: rgb(153,153,187) 1px solid" class=FCK__ShowTableBorders border=0 cellSpacing=2 cellPadding=1 width="100%" align=center>
    <tbody>
        <tr>
            <td bgColor=#dfefef><font color=#000000>
            <p style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 3px; MARGIN-LEFT: 5px">// 用{}运算符，还记得么？网中人的教程。<br>$ var="get the length of me"<br>$ echo ${var/ /_}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #把第一个空格替换成下划线<br>get_the length of me<br>$ echo ${var// /_}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #把所有空格都替换成了下划线了<br>get_the_length_of_me<br><br>// 用awk，awk提供了转换的最小替换函数sub和全局替换函数gsub，类似/和//<br>$ echo $var | awk '{sub(" ", "_", $0); printf("%s\n", $0);}'<br>get_the length of me<br>$ echo $var | awk '{gsub(" ", "_", $0); printf("%s\n", $0);}'<br>get_the_length_of_me<br><br>// 用sed了，子串替换可是sed的特长<br>$ echo $var | sed -e 's/ /_/'&nbsp;&nbsp; #s &lt;= substitude<br>get_the length of me<br>$ echo $var | sed -e 's/ /_/g'&nbsp;&nbsp; #看到没有，简短两个命令就实现了最小匹配和最大匹配g &lt;= global<br>get_the_length_of_me<br><br>// 有忘记tr命令么？可以用替换单个字符的<br>$ echo $var | tr " " "_"<br>get_the_length_of_me<br>$ echo $var | tr '[a-z]' '[A-Z]'&nbsp;&nbsp; #这个可有意思了，把所有小写字母都替换为大写字母<br>GET THE LENGTH OF ME</p>
            </font></td>
        </tr>
    </tbody>
</table>
<br><br>说明：sed还有很有趣的标签用法呢，下面再介绍吧。<br><br>有一种比较有意思的字符串替换是，整个文件行的倒置，这个可以通过tac命令实现，它会把文件中所有的行全部倒转过来。在一定意义上来说，排序实际上也是一个字符串替换。<br><br><font color=#ff0000>2.4. 插入子串</font><br><br>插入子串：就是在指定的位置插入子串，这个位置可能是某个子串的位置，也可能是从某个文件开头算起的某个长度。通过上面的练习，我们发现这两者之间实际上是类似的。<br><br>公式：插入子串=把"old子串"替换成"old子串+new子串"或者"new子串+old子串"<br><br>概要示例：：下面在var字符串的空格之前或之后插入一个下划线<br><br>
<table style="BORDER-BOTTOM: rgb(153,153,187) 1px solid; BORDER-TOP: rgb(153,153,187) 1px solid" class=FCK__ShowTableBorders border=0 cellSpacing=2 cellPadding=1 width="100%" align=center>
    <tbody>
        <tr>
            <td bgColor=#dfefef><font color=#000000>
            <p style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 3px; MARGIN-LEFT: 5px">// 用{}<br>$ var="get the length of me"<br>$ echo ${var/ /_ }&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #在指定字符串之前插入一个字符串<br>get_ the length of me<br>$ echo ${var// /_ }<br>get_ the_ length_ of_ me<br>$ echo ${var/ / _}&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #在指定字符串之后插入一个字符串<br>get _the length of me<br>$ echo ${var// / _}<br>get _the _length _of _me<br><br>// 其他的还用演示么？这里主要介绍sed怎么用来插入字符吧，因为它的标签功能很有趣<br>$ echo $var | sed -e 's/\( \)/_\1/' #\(和\)将不匹配到的字符串存放为一个标签，按匹配顺序为\1,\2...<br>get_ the length of me<br>$ echo $var | sed -e 's/\( \)/_\1/g'<br>get_ the_ length_ of_ me<br>$ echo $var | sed -e 's/\( \)/\1_/'<br>get _the length of me<br>$ echo $var | sed -e 's/\( \)/\1_/g'<br>get _the _length _of _me<br><br>// 看看sed的标签的顺序是不是\1,\2....，看到没？\2和\1掉换位置后，the和get的位置掉换了<br>$ echo $var | sed -e 's/\([a-z]*\) \([a-z]*\) /\2 \1 /g'<br>the get of length me<br>// sed还有专门的插入指令，a和i,分别表示在匹配的行后和行前插入指定字符<br>$ echo $var | sed '/get/a test'<br>get the length of me<br>test<br>$ echo $var | sed '/get/i test'<br>test<br>get the length of me</p>
            </font></td>
        </tr>
    </tbody>
</table>
<br><font color=#ff0000>2.5. 删除子串</font>删除子串：应该很简单了吧，把子串替换成&#8220;空&#8221;（什么都没有）不就变成了删除么。还是来简单复习一下替换吧。概要示例：：把var字符串中所有的空格给删除掉。鼓励：这样一替换不知道变成什么单词啦，谁认得呢？但是中文却是连在一起的，所以中文有多难，你想到了么？原来你也是个语言天才，而英语并不可怕，你有学会它的天赋，只要你有这个打算。如果要删除掉第一个空格后面所有的字符串该怎么办呢？还记得{}的#和%用法么？如果不记得，回到这一节的还头开始复习吧。（实际上删除子串和取子串未尝不是两种互补的运算呢，删除掉某些不想要的子串，也就同时取得另外那些想要的子串——这个世界就是一个&#8220;二元&#8221;的世界，非常有趣）这个很简单：还记得test命令的用法么？man test。它可以用来判断两个字符串是否相等的。另外，你发现了&#8220;字符串是否相等&#8221;和&#8220;字符串能否跟另外一个字符串匹配"两个问题之间的关系吗？如果两个字符串完全匹配，那么这两个字符串就相等了。所以呢，上面用到的字符串匹配方法，也同样可以用到这里。差点忘记这个重要的内容了，子串排序可是经常用到的，常见的有按字母序、数字序等正序或反序排列。sort命令可以用来做这个工作，它和其他行处理命令一样，是按行操作的，另外，它类似cut和awk，可以指定分割符，并指定需要排序的列。如果字母和数字字符用来计数，那么就存在进制转换的问题。在数值计算一节的回复资料里，我们已经介绍了bc命令，这里再简单的复习一下。说明：ibase指定输入进制，obase指出输出进制，这样通过调整ibase和obase，你想怎么转就怎么转啦！什么是字符编码？这个就不用介绍了吧，看过那些乱七八糟显示的网页么？大多是因为浏览器显示时的&#8221;编码&#8220;和网页实际采用的&#8221;编码&#8220;不一致导致的。字符编码通常是指把一序列&#8221;可打印&#8220;字符转换成二进制表示，而字符解码呢则是执行相反的过程，如果这两个过程不匹配，则出现了所谓的&#8221;乱码&#8220;。为了解决&#8221;乱码&#8220;问题呢？就需要进行编码转换。在linux下，我们可以使用iconv这个工具来进行相关操作。这样的情况经常在不同的操作系统之间移动文件，不同的编辑器之间交换文件的时候遇到，目前在windows下常用的汉字编码是gb2312，而在linux下则大多采用utf8。说明：我的终端默认编码是utf8，所以结果如上。实际上，在用Bash编程时，大部分时间都是在处理字符串，因此把这一节熟练掌握非常重要。范例演示：处理URL地址URL地址 (URL（Uniform Resoure Locator：统一资源定位器）是WWW页的地址)几乎是我们日常生活的玩伴，我们已经到了无法离开它的地步啦，对它的操作很多，包括判断URL地址的有效性，截取地址的各个部分（服务器类型、服务器地址、端口、路径等）并对各个部分进行进一步的操作。下面我们来具体处理这个URL地址：有了上面的知识，我们就可以非常容易地进行这些工作啦：修改某个文件的文件名，比如调整它的编码，下载某个网页里头的所有pdf文档等。这些就作为练习自己做吧，如果遇到问题，可以在回帖交流。相应地可以参考这个例子：[1] 用脚本下载某个网页中的英文原著(pdf文档）平时做工作，大多数时候处理的都是一些&#8220;格式化&#8221;的文本，比如类似/etc/passwd这样的有固定行和列的文本，也有类似tree命令输出的那种具有树形结构的文本，当然还有其他具有特定结构的文本。关于树状结构的文本的处理，可以考虑看看这两个例子： [1] 用AWK转换树形数据成关系表[2] 用Graphviz进行可视化操作──绘制函数调用关系图实际上，只要把握好特性结构的一些特点，并根据具体的应用场合，处理起来就不会困难。下面我们来介绍具体有固定行和列的文本的操作，以/etc/passwd文件为例。关于这个文件的帮忙和用户，请通过man 5 passwd查看。下面我们对这个文件以及相关的文件进行一些有意义的操作。上面涉及到了处理某格式化行中的指定列，包括截取（如SQL的select用法），连接（如SQL的join用法），排序（如SQL的order by用法)，都可以通过指定分割符来拆分某个格式化的行，另外，&#8220;截取&#8221;的做法还有很多，不光是cut，awk，甚至通过IFS指定分割符的read命令也可以做到，例如：因此，熟悉这些用法，我们的工作将变得非常灵活有趣。到这里，需要做一个简单的练习，如何把按照列对应的用户名和用户ID转换成按照行对应的，即把类似下面的数据：转换成：并转换回去，有什么办法呢？记得诸如tr，paste,split等命令都可以使用。参考方法：＊正转换：先截取用户名一列存入文件user，再截取用户ID存入id，再把两个文件用paste -s命令连在一起，这样就完成了正转换。＊逆转换：先把正转换得到的结果用split -1拆分成两个文件，再把两个拆分后的文件用tr把分割符"\t"替换成"\n"，只有用paste命令把两个文件连在一起，这样就完成了逆转换。更多有趣的例子，可以参考该序列第一部分的回复，即参考资料[16]的回复，以及兰大开源社区镜像站用的镜像脚本，即参考资料[17]，另外，参考资料[18] 关于用Shell实现一个五笔反查小工具也值得阅读和改进。<br><br><br>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/86393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-06-01 14:08 <a href="http://www.cppblog.com/beautykingdom/archive/2009/06/01/86393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sed使用心得&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2009/04/01/78546.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Wed, 01 Apr 2009 03:53:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2009/04/01/78546.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/78546.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2009/04/01/78546.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/78546.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/78546.html</trackback:ping><description><![CDATA[<p><font face="Courier New">sed 是一种UNIX/LINUX 平台下的轻量级流编辑器，日常一般用于处理文本文件。sed 有许多很好的特性。首先，它相当小巧；其次， sed 可以配合强大的 shell 完成许多复杂的功能。在我看来，sed完全可以看成一个脚本解释器，用类似于编程的手段完成许多事情。</font></p>
<p><font face="Courier New"><strong>sed简单示例</strong></font></p>
<p><font face="Courier New">sed命令的格式是 <br>sed [-options] [command] [stdin] <br>比如这个例子 <br>$ sed &#8211;e &#8216;d&#8217; ./Mydir/Myfile <br>执行该命令，将得不到任何输出。在该例中，用一个编辑命令 'd' 调用 sed；sed 打开 ./Mydir/Myfile 将一行读入其模式缓冲区，执行&#8217;d&#8217;（&#8220;删除行&#8221;）；然后打印模式缓冲区（缓冲区已为空）；它对后面的每一行重复这些步骤，这不会产生输出！<br>对这个命令要说明的几点是：首先，它根本没有修改 ./Mydir/Myfile。这是因为 sed 是流处理器，它只读取在命令行指定的文件，它不试图修改该文件。其次， sed 是面向行的，'d' 命令不是简单地告诉 sed 一下子删除所有输入数据；相反，sed 逐行将 ./Mydir/Myfile 的每一行读入其称为模式缓冲区的内部缓冲区，一旦将一行读入模式缓冲区，它就执行 'd' 命令，然后打印模式缓冲区的内容。最后要注意的事是括起 'd' 命令的单引号的用法，这样可以禁用 shell 扩展。</font></p>
<p><font face="Courier New"><strong>指定sed的作用范围</strong></font></p>
<p><font face="Courier New">看下面的三个例子<br>&nbsp;$ sed &#8211;e &#8216;1d&#8217; ./Mydir/Myfile<br>&nbsp;$ sed &#8211;e &#8216;1,10d&#8217; ./Mydir/Myfile<br>&nbsp;$ sed &#8211;e &#8216;/begin/,/end/p&#8217; ./Mydir/Myfile<br>第一个例子说明只删除./Mydir/Myfile第一行的缓冲，第二个例子将删除第1~10行的缓冲。第三个例子最复杂，它定义了以字符串&#8217;begin&#8217;开始到&#8217;end&#8217;结束的作用范围</font></p>
<p><font face="Courier New"><strong>sed中的正则表达式</strong></font></p>
<p><font face="Courier New">sed支持正则表达式，比如<br>&nbsp;$ sed &#8211;n -e &#8216;/regexp/p&#8217; ./Mydir/Myfile<br>比如要删除所有的空行<br>&nbsp;$ sed &#8211;e &#8216;/^$/d&#8217; ./Mydir/Myfile<br>sed中的一些特殊定义是<br><em>&nbsp;&nbsp;&nbsp; <strong>规则 表达式&nbsp;&nbsp;&nbsp;&nbsp;描述</strong> <br>&nbsp;&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>&nbsp;&nbsp;&nbsp; /^$/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将与所有空行匹配<br>&nbsp;&nbsp;&nbsp; /}^/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将与以 '}'（无空格）结束的任何行匹配<br>&nbsp;&nbsp;&nbsp; /} *^/&nbsp;&nbsp;&nbsp; 将与以 '}' 后面跟有 零或多个空格结束的任何行匹配 <br>&nbsp;&nbsp;&nbsp; /[abc]/&nbsp;&nbsp;&nbsp;将与包含小写 'a'、'b' 或 'c' 的任何行匹配<br>&nbsp;&nbsp;&nbsp; /^[abc]/&nbsp;&nbsp;将与以 'a'、'b' 或 'c' 开始的任何行匹配</em><br>再比如一个经典的例子，打印c源代码中的main函数内容，其命令可以写成如下<br>&nbsp;$ sed &#8211;n &#8211;e &#8216;/main[[:space]]*(/,/^}/p&#8217; ./Mydir/*.c<br>其中[:space]表示空格，[[:space]]*表示有0~多个空格，所以main[[:space]]*(的意思是匹配&#8220;main (&#8221;字符串；&#8220;^}&#8221;表示这一行有且只有一个字符}。当然，上面的命令不是十分严谨。</font></p>
<p><font face="Courier New"><strong>sed &#8211;e &#8216;s/regexp/repalcement&#8217; file</strong></font></p>
<p><font face="Courier New">替换是sed命令中最常用的命令，比如如下的例子<br>&nbsp;$ sed &#8211;e &#8216;s/a/b&#8217; ./Mydir/Myfile<br>&nbsp;$ sed &#8211;e &#8216;s/a/b/g&#8217; ./Mydir/Myfile<br>第一个命令将./Mydir/Myfile中每一行第一次出现的字符a替换成字符b；第二个命令由于加入了&#8217;/g&#8217;，表示是全局（全部）替换字符a成字符b。</font></p>
<p><font face="Courier New">经常还可以看见如下两种形式的sed<br>&nbsp;$ sed &#8211;e &#8216;1,10s/a/b&#8217; ./Mydir/Myfile<br>&nbsp;$ sed &#8211;e &#8216;/^$/,/^END/s/a/b/g&#8217; ./Mydir/Myfile<br>第一个命令是指替换1~10行；第二个命令是指全局替换从空行开始到以END开始的行中的内容。</font></p>
<p><font face="Courier New">替换命令不一定非要以/分隔，比如<br>&nbsp;$ sed &#8211;e &#8216;s:usr/local:/usr:g&#8217; ./Mydir/Myfile<br>就是将./Mydir/Myfile中的usr/local全部替换成/usr</font></p>
<p><font face="Courier New">要用好替换命令，当然要使用正则表达式，除了上面所说的表达式的例子，还有一些是非常有用的<br><em><strong>&nbsp;&nbsp;&nbsp; 字符类&nbsp;&nbsp;&nbsp;描述</strong><br>&nbsp;&nbsp;&nbsp; [:alnum:]&nbsp;&nbsp;字母数字 [a-z A-Z 0-9]<br>&nbsp;&nbsp;&nbsp; [:alpha:]&nbsp;&nbsp;字母 [a-z A-Z]<br>&nbsp;&nbsp;&nbsp; [:blank:]&nbsp;&nbsp;空格或制表键<br>&nbsp;&nbsp;&nbsp; [:cntrl:]&nbsp;&nbsp;任何控制字符<br>&nbsp;&nbsp;&nbsp; [:digit:]&nbsp;&nbsp;数字 [0-9]<br>&nbsp;&nbsp;&nbsp; [:graph:]&nbsp;&nbsp;任何可视字符（无空格）<br>&nbsp;&nbsp;&nbsp; [:lower:]&nbsp;&nbsp;小写 [a-z]<br>&nbsp;&nbsp;&nbsp; [:print:]&nbsp;&nbsp;非控制字符<br>&nbsp;&nbsp;&nbsp; [:punct:]&nbsp;&nbsp;标点字符<br>&nbsp;&nbsp;&nbsp; [:space:]&nbsp;&nbsp;空格<br>&nbsp;&nbsp;&nbsp; [:upper:]&nbsp;&nbsp;大写 [A-Z]<br>&nbsp;&nbsp;&nbsp; [:xdigit:]&nbsp;&nbsp;十六进制数字 [0-9 a-f A-F]</em><br>比如下面这个例子<br>&nbsp;$ sed &#8211;e &#8216;s/&lt;[^&gt;]*&gt;//g&#8217; ./Mydir/Myfile<br>&lt; [^&gt;]*&gt;匹配&lt;&#8230;&gt;这样的字符串（&#8230;中不含&gt;）。运行这个命令，能够将 &#8220;&lt;b&gt;This&lt;/b&gt; is what &lt;b&gt;I&lt;/b&gt; meant.&#8221;这样的字符串替换成&#8220;This is what I meant.&#8221;</font></p>
<p><font face="Courier New">考察如下的命令<br>&nbsp;$ sed -e 's/.*/# &amp;/' ./Mydir/Myfile<br>这个命令将所有的非空行以&#8220;#&#8221;注释掉——&amp;告诉sed在行首插入字符。</font></p>
<p><font face="Courier New">&#8216;s///&#8217;允许我们在规则表达式中定义区域，然后可以在替换字符串中引用这些特定区域。这些区域是以\(和\)隔开的。<br>比如定义三个匹配非空字符的区域'\(.*\) \(.*\) \(.*\)'，现在可以定义这三个区域的动作，比如<br>&nbsp;$ sed -e 's/\(.*\) \(.*\) \(.*\)/PreFix \1-\2 Fix \3/' ./Mydir/Myfile<br>假如把三个区域分别命名为a、b、c，则最后结果是 PreFix a-b Fix c</font></p>
<p><font face="Courier New"><strong>sed中组合命令</strong></font></p>
<p><font face="Courier New">sed中的命令可以组合，以；号隔开，比如<br>&nbsp;$ sed &#8211;n &#8211;e &#8216;=;p&#8217; ./Mydir/Myfile<br>=表示打印行号，p表示打印。对于更复杂的指令，则可以写成命令脚本，然后用-f选项导入，比如<br>&nbsp;$ sed &#8211;n &#8211;f MyScript.sed ./Mydir/Myfile<br>对于同一个地址上的操作，则可以用{}组合，比如<br>&nbsp;$ sed &#8211;n &#8216;1,20{ s/samba/Samba/g &nbsp;s/posix/POSIX/g }&#8217; ./Mydir/Myfile</font></p>
<p><font face="Courier New"><strong>sed中的行附加命令</strong></font></p>
<p><font face="Courier New">在当前行之前插入行&#8220;i\&#8221;，如果要插入多行，则将多行用\分隔<br>在当前行之后插入行&#8220;a\&#8221;，用法和上面相似<br>更改当前行&#8220;c\&#8221;</font></p>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/78546.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2009-04-01 11:53 <a href="http://www.cppblog.com/beautykingdom/archive/2009/04/01/78546.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>