📄 moreadv.html
字号:
23 # 像 Frank Wang 所指出, 24 #+ 在原文件中的任何不匹配的引号(包括单引号和双引号) 25 #+ 都会给xargs造成麻烦. 26 # 27 # 他建议使用下边的这行来替换上边的第15行: 28 # tail -$LINES /var/log/messages | tr -d "\"'" | xargs | fmt -s >>logfile 29 30 31 32 # 练习: 33 # ----- 34 # 修改这个脚本, 使得这个脚本每个20分钟 35 #+ 就跟踪一下 /var/log/messages 的修改记录. 36 # 提示: 使用 "watch" 命令. </PRE></FONT></TD></TR></TABLE><HR></DIV><P><AHREF="moreadv.html#CURLYBRACKETSREF">As in <BCLASS="COMMAND">find</B></A>, a curly bracket pair serves as a placeholder for replacement text.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX42"></A><P><B>例子 12-6. 把当前目录下的文件拷贝到另一个文件中</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # copydir.sh 3 4 # 将当前目录下($PWD)的所有文件都拷贝到 5 #+ 命令行所指定的另一个目录中去. 6 7 E_NOARGS=65 8 9 if [ -z "$1" ] # 如果没有参数传递进来那就退出. 10 then 11 echo "Usage: `basename $0` directory-to-copy-to" 12 exit $E_NOARGS 13 fi 14 15 ls . | xargs -i -t cp ./{} $1 16 # ^^ ^^ ^^ 17 # -t 是 "verbose" (输出命令行到stderr) 选项. 18 # -i 是"替换字符串"选项. 19 # {} 是输出文本的替换点. 20 # 这与在"find"命令中使用{}的情况很相像. 21 # 22 # 列出当前目录下的所有文件(ls .), 23 #+ 将 "ls" 的输出作为参数传递到 "xargs"(-i -t 选项) 中, 24 #+ 然后拷贝(cp)这些参数({})到一个新目录中($1). 25 # 26 # 最终的结果和下边的命令等价, 27 #+ cp * $1 28 #+ 除非有文件名中嵌入了"空白"字符. 29 30 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="KILLBYNAME"></A><P><B>例子 12-7. 通过名字kill进程</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # kill-byname.sh: 通过名字kill进程. 3 # 与脚本kill-process.sh相比较. 4 5 # 例如, 6 #+ 试一下 "./kill-byname.sh xterm" -- 7 #+ 并且查看你系统上的所有xterm都将消失. 8 9 # 警告: 10 # ----- 11 # 这是一个非常危险的脚本. 12 # 运行它的时候一定要小心. (尤其是以root身份运行时) 13 #+ 因为运行这个脚本可能会引起数据丢失或产生其他一些不好的效果. 14 15 E_BADARGS=66 16 17 if test -z "$1" # 没有参数传递进来? 18 then 19 echo "Usage: `basename $0` Process(es)_to_kill" 20 exit $E_BADARGS 21 fi 22 23 24 PROCESS_NAME="$1" 25 ps ax | grep "$PROCESS_NAME" | awk '{print $1}' | xargs -i kill {} 2&>/dev/null 26 # ^^ ^^ 27 28 # ----------------------------------------------------------- 29 # 注意: 30 # -i 参数是xargs命令的"替换字符串"选项. 31 # 大括号对的地方就是替换点. 32 # 2&>/dev/null 将会丢弃不需要的错误消息. 33 # ----------------------------------------------------------- 34 35 exit $? 36 37 # 在这个脚本中, "killall"命令具有相同的效果, 38 #+ 但是这么做就没有教育意义了.</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="WF2"></A><P><B>例子 12-8. 使用<BCLASS="COMMAND">xargs</B><BCLASS="COMMAND">分析单词出现的频率</B></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # wf2.sh: 分析一个文本文件中单词出现的频率. 3 4 # 使用 'xargs' 将文本行分解为单词. 5 # 与后边的 "wf.sh" 脚本相比较. 6 7 8 # 检查命令行上输入的文件. 9 ARGS=1 10 E_BADARGS=65 11 E_NOFILE=66 12 13 if [ $# -ne "$ARGS" ] 14 # 纠正传递到脚本中的参数个数? 15 then 16 echo "Usage: `basename $0` filename" 17 exit $E_BADARGS 18 fi 19 20 if [ ! -f "$1" ] # 检查文件是否存在. 21 then 22 echo "File \"$1\" does not exist." 23 exit $E_NOFILE 24 fi 25 26 27 28 ##################################################################### 29 cat "$1" | xargs -n1 | \ 30 # 列出文件, 每行一个单词. 31 tr A-Z a-z | \ 32 # 将字符转换为小写. 33 sed -e 's/\.//g' -e 's/\,//g' -e 's/ /\ 34 /g' | \ 35 # 过滤掉句号和逗号, 36 #+ 并且将单词间的空格修改为换行, 37 sort | uniq -c | sort -nr 38 # 最后统计出现次数, 把数字显示在第一列, 然后显示单词, 并按数字排序. 39 ##################################################################### 40 41 # 这个例子的作用与"wf.sh"的作用是一样的, 42 #+ 但是这个例子比较臃肿, 并且运行起来更慢一些(为什么?). 43 44 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><ANAME="EXPRREF"></A><KBDCLASS="USERINPUT">expr</KBD></DT><DD><P>通用求值表达式: 通过给定的操作(参数必须以空格分开)连接参数, 并对参数求值. 可以使算术操作, 比较操作, 字符串操作或者是逻辑操作. </P><P></P><DIVCLASS="VARIABLELIST"><DL><DT><KBDCLASS="USERINPUT">expr 3 + 5</KBD></DT><DD><P>返回<TTCLASS="LITERAL">8</TT></P></DD><DT><KBDCLASS="USERINPUT">expr 5 % 3</KBD></DT><DD><P>返回2</P></DD><DT><KBDCLASS="USERINPUT">expr 1 / 0</KBD></DT><DD><P>返回错误消息, <EM>expr: division by zero</EM></P><P>不允许非法的算术操作. </P></DD><DT><KBDCLASS="USERINPUT">expr 5 \* 3</KBD></DT><DD><P>返回15</P><P>在算术表达式<BCLASS="COMMAND">expr</B>中使用乘法操作时, 乘法符号必须被转义. </P></DD><DT><KBDCLASS="USERINPUT">y=`expr $y + 1`</KBD></DT><DD><P>增加变量的值, 与<KBDCLASS="USERINPUT">let y=y+1</KBD>和<KBDCLASS="USERINPUT">y=$(($y+1))</KBD>的效果相同. 这是使用<AHREF="arithexp.html#ARITHEXPREF">算术表达式</A>的一个例子. </P></DD><DT><ANAME="EXPEXTRSUB"></A><KBDCLASS="USERINPUT">z=`expr substr $string $position $length`</KBD></DT><DD><P>在位置$position上提取$length长度的子串. </P></DD></DL></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="EX45"></A><P><B>例子 12-9. 使用<BCLASS="COMMAND">expr</B></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # 展示一些使用'expr'的例子 4 # ======================== 5 6 echo 7 8 # 算术 操作 9 # ---- ---- 10 11 echo "Arithmetic Operators" 12 echo 13 a=`expr 5 + 3` 14 echo "5 + 3 = $a" 15 16 a=`expr $a + 1` 17 echo 18 echo "a + 1 = $a" 19 echo "(incrementing a variable)" 20 21 a=`expr 5 % 3` 22 # 取模操作 23 echo 24 echo "5 mod 3 = $a" 25 26 echo 27 echo 28 29 # 逻辑 操作 30 # ---- ---- 31 32 # true返回1, false返回0, 33 #+ 而Bash的使用惯例则相反. 34 35 echo "Logical Operators" 36 echo 37 38 x=24 39 y=25 40 b=`expr $x = $y` # 测试相等. 41 echo "b = $b" # 0 ( $x -ne $y ) 42 echo 43 44 a=3 45 b=`expr $a \> 10` 46 echo 'b=`expr $a \> 10`, therefore...' 47 echo "If a > 10, b = 0 (false)" 48 echo "b = $b" # 0 ( 3 ! -gt 10 ) 49 echo 50 51 b=`expr $a \< 10` 52 echo "If a < 10, b = 1 (true)" 53 echo "b = $b" # 1 ( 3 -lt 10 ) 54 echo 55 # 注意转义操作. 56 57 b=`expr $a \<= 3` 58 echo "If a <= 3, b = 1 (true)" 59 echo "b = $b" # 1 ( 3 -le 3 ) 60 # 也有 "\>=" 操作 (大于等于). 61 62 63 echo 64 echo 65 66 67 68 # 字符串 操作 69 # ------ ---- 70 71 echo "String Operators" 72 echo 73 74 a=1234zipper43231 75 echo "The string being operated upon is \"$a\"." 76 77 # 长度: 字符串长度 78 b=`expr length $a` 79 echo "Length of \"$a\" is $b." 80 81 # 索引: 从字符串的开头查找匹配的子串, 82 # 并取得第一个匹配子串的位置. 83 b=`expr index $a 23` 84 echo "Numerical position of first \"2\" in \"$a\" is \"$b\"." 85 86 # substr: 从指定位置提取指定长度的字串. 87 b=`expr substr $a 2 6` 88 echo "Substring of \"$a\", starting at position 2,\ 89 and 6 chars long is \"$b\"." 90 91 92 # 'match' 操作的默认行为就是从字符串的开始进行搜索, 93 #+ 并匹配第一个匹配的字符串. 94 # 95 # 使用正则表达式 96 b=`expr match "$a" '[0-9]*'` # 数字的个数. 97 echo Number of digits at the beginning of \"$a\" is $b. 98 b=`expr match "$a" '\([0-9]*\)'` # 注意, 需要转义括号 99 # == == + 这样才能触发子串的匹配.100 echo "The digits at the beginning of \"$a\" are \"$b\"."101 102 echo103 104 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="IMPORTANT"><P></P><TABLECLASS="IMPORTANT"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/important.gif"HSPACE="5"ALT="Important"></TD><TDALIGN="LEFT"VALIGN="TOP"><P><AHREF="special-chars.html#NULLREF">:</A>操作可以替换<BCLASS="COMMAND">match</B>命令. 比如, <KBDCLASS="USERINPUT">b=`expr $a : [0-9]*`</KBD>与上边所使用的<KBDCLASS="USERINPUT">b=`expr match $a [0-9]*`</KBD>完全等价. </P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 echo 4 echo "String operations using \"expr \$string : \" construct" 5 echo "===================================================" 6 echo 7 8 a=1234zipper5FLIPPER43231 9 10 echo "The string being operated upon is \"`expr "$a" : '\(.*\)'`\"." 11 # 转义括号对的操作. == == 12 13 # *************************** 14 #+ 转义括号对 15 #+ 用来匹配一个子串 16 # *************************** 17 18 19 # 如果不转义括号的话... 20 #+ 那么'expr'将把string操作转换为一个整数. 21 22 echo "Length of \"$a\" is `expr "$a" : '.*'`." # 字符串长度 23 24 echo "Number of digits at the beginning of \"$a\" is `expr "$a" : '[0-9]*'`." 25 26 # ------------------------------------------------------------------------- # 27 28 echo 29 30 echo "The digits at the beginning of \"$a\" are `expr "$a" : '\([0-9]*\)'`." 31 # == == 32 echo "The first 7 characters of \"$a\" are `expr "$a" : '\(.......\)'`." 33 # ===== == == 34 # 再来一个, 转义括号对强制一个子串匹配. 35 # 36 echo "The last 7 characters of \"$a\" are `expr "$a" : '.*\(.......\)'`." 37 # ==== 字符串操作的结尾 ^^ 38 # (最后这个模式的意思是忽略前边的任何字符,直到最后7个字符, 39 #+ 最后7个点就是需要匹配的任意7个字符的字串) 40 41 echo 42 43 exit 0</PRE></FONT></TD></TR></TABLE></P></TD></TR></TABLE></DIV></DD></DL></DIV><P>上边的脚本展示了<BCLASS="COMMAND">expr</B>如何使用<EM>转义括号对-- \( ... \) --</EM> 和<AHREF="regexp.html#REGEXREF">正则表达式</A>一起来分析和匹配子串. 下边是另外一个例子, 这次的例子是真正的<SPANCLASS="QUOTE">"应用用例"</SPAN>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 # 去掉字符串开头和结尾的空白. 2 LRFDATE=`expr "$LRFDATE" : '[[:space:]]*\(.*\)[[:space:]]*$'` 3 4 # 来自于Peter Knowle的"booklistgen.sh"脚本 5 #+ 用来将文件转换为Sony Librie格式. 6 # (http://booklistgensh.peterknowles.com)</PRE></FONT></TD></TR></TABLE> </P><P><AHREF="wrapper.html#PERLREF">Perl</A>, <AHREF="sedawk.html#SEDREF">sed</A>, 和<AHREF="awk.html#AWKREF">awk</A>是更强大的字符串分析工具. 在脚本中加入一段比较短的<BCLASS="COMMAND">sed</B>或者<BCLASS="COMMAND">awk</B><SPANCLASS="QUOTE">"子程序"</SPAN>(参考<AHREF="wrapper.html">Section 33.2</A>), 比使用<BCLASS="COMMAND">expr</B>更有吸引力. </P><P>参考<AHREF="string-manipulation.html">Section 9.2</A>可以了解到更多使用<BCLASS="COMMAND">expr</B>进行字符串操作的例子. </P></DIV><H3CLASS="FOOTNOTES">注意事项</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN7492"HREF="moreadv.html#AEN7492"><SPANCLASS="footnote">[1]</SPAN></A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>即使在某些不必非得强制使用<ICLASS="FIRSTTERM">xargs</I>的情况下, 使用这个命令也会明显的提高多文件批处理执行命令的速度. </P></TD></TR></TABLE><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="basic.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">首页</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="timedate.html"ACCESSKEY="N">下一页</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">基本命令</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="external.html"ACCESSKEY="U">上一级</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">时间/日期 命令</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -