string-manipulation.html
来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 1,376 行 · 第 1/2 页
HTML
1,376 行
></TT>的<EM>开头</EM>位置截掉最长匹配的<TTCLASS="REPLACEABLE"><I>$substring</I></TT>. </P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 stringZ=abcABC123ABCabc 2 # |----| 3 # |----------| 4 5 echo ${stringZ#a*C} # 123ABCabc 6 # 截掉'a'到'C'之间最短的匹配字符串. 7 8 echo ${stringZ##a*C} # abc 9 # 截掉'a'到'C'之间最长的匹配字符串.</PRE></FONT></TD></TR></TABLE> </P></DD><DT>${string%substring}</DT><DD><P>从<TTCLASS="REPLACEABLE"><I>$string</I></TT>的<EM>结尾</EM>位置截掉最短匹配的<TTCLASS="REPLACEABLE"><I>$substring</I></TT>. </P></DD><DT>${string%%substring}</DT><DD><P>从<TTCLASS="REPLACEABLE"><I>$string</I></TT>的<EM>结尾</EM>位置截掉最长匹配的<TTCLASS="REPLACEABLE"><I>$substring</I></TT>. </P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 stringZ=abcABC123ABCabc 2 # || 3 # |------------| 4 5 echo ${stringZ%b*c} # abcABC123ABCa 6 # 从$stringZ的结尾位置截掉'b'到'c'之间最短的匹配. 7 8 echo ${stringZ%%b*c} # a 9 # 从$stringZ的结尾位置截掉'b'到'c'之间最长的匹配. </PRE></FONT></TD></TR></TABLE> </P><P>当你需要构造文件名的时候, 这个操作就显得特别有用. </P><DIVCLASS="EXAMPLE"><HR><ANAME="CVT"></A><P><B>例子 9-11. 转换图片文件格式, 同时更改文件名</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # cvt.sh: 3 # 将一个目录下的所有MacPaint格式的图片文件都转换为"pbm"各式的图片文件. 4 5 # 使用"netpbm"包中的"macptopbm"程序进行转换, 6 #+ 这个程序主要是由Brian Henderson(bryanh@giraffe-data.com)来维护的. 7 # Netpbm绝大多数Linux发行版的标准套件. 8 9 OPERATION=macptopbm 10 SUFFIX=pbm # 新的文件名后缀. 11 12 if [ -n "$1" ] 13 then 14 directory=$1 # 如果目录名作为参数传递给脚本... 15 else 16 directory=$PWD # 否则使用当前的工作目录. 17 fi 18 19 # 假定目标目录中的所有文件都是MacPaint格式的图像文件, 20 #+ 并且都是以".mac"作为文件名后缀. 21 22 for file in $directory/* # 文件名匹配(filename globbing). 23 do 24 filename=${file%.*c} # 去掉文件名的".mac"后缀 25 #+ ('.*c' 将会匹配 26 #+ '.'和'c'之间任意字符串). 27 $OPERATION $file > "$filename.$SUFFIX" 28 # 把结果重定向到新的文件中. 29 rm -f $file # 转换后删除原始文件. 30 echo "$filename.$SUFFIX" # 从stdout输出转换后文件的文件名. 31 done 32 33 exit 0 34 35 # 练习: 36 # ----- 37 # 就像它现在的样子, 这个脚本把当前 38 #+ 目录下的所有文件都转换了. 39 # 修改这个脚本, 让它只转换以".mac"为后缀名的文件.</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="RA2OGG"></A><P><B>例子 9-12. 将音频流文件转换为<EM>ogg</EM>各式的文件</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # ra2ogg.sh: 将音频流文件(*.ra)转换为ogg格式的文件. 3 4 # 使用"mplayer"媒体播放器程序: 5 # http://www.mplayerhq.hu/homepage 6 # 可能需要安装合适的编解码程序(codec)才能够正常的运行这个脚本. 7 # 需要使用"ogg"库和"oggenc": 8 # http://www.xiph.org/ 9 10 11 OFILEPREF=${1%%ra} # 去掉"ra"后缀. 12 OFILESUFF=wav # wav文件的后缀. 13 OUTFILE="$OFILEPREF""$OFILESUFF" 14 E_NOARGS=65 15 16 if [ -z "$1" ] # 必须要指定一个需要转换的文件名. 17 then 18 echo "Usage: `basename $0` [filename]" 19 exit $E_NOARGS 20 fi 21 22 23 ########################################################################## 24 mplayer "$1" -ao pcm:file=$OUTFILE 25 oggenc "$OUTFILE" # oggenc编码后会自动加上正确的文件扩展名. 26 ########################################################################## 27 28 rm "$OUTFILE" # 删除中介的*.wav文件. 29 # 如果你想保留这个文件的话, 可以把上边这行注释掉. 30 31 exit $? 32 33 # 注意: 34 # ---- 35 # 在网站上, 简单的在*.ram流音频文件上单击的话, 36 #+ 一般都只会下载真正音频流文件(就是*.ra文件)的URL. 37 # 你可以使用"wget"或者一些类似的工具 38 #+ 来下载*.ra文件本身. 39 40 41 # 练习: 42 # ----- 43 # 像上面所看到的, 这个脚本只能够转换*.ra文件. 44 # 给这个脚本添加一些灵活性, 让它能够转换*.ram and other filenames. 45 # 46 # 如果你觉得这还不过瘾, 那么你可以扩展这个脚本, 47 #+ 让它自动下载并转换音频流文件. 48 # 给出一个URL, (使用"wget")批处理下载音频流文件, 49 #+ 然后转换它们.</PRE></FONT></TD></TR></TABLE><HR></DIV><P>一个简单的<AHREF="extmisc.html#GETOPTY">getopt</A>命令的模拟, 使用子串提取结构.</P><DIVCLASS="EXAMPLE"><HR><ANAME="GETOPTSIMPLE"></A><P><B>例子 9-13. 模拟<EM>getopt</EM></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # getopt-simple.sh 3 # 作者: Chris Morgan 4 # 已经经过授权, 可以使用在本书中. 5 6 7 getopt_simple() 8 { 9 echo "getopt_simple()" 10 echo "Parameters are '$*'" 11 until [ -z "$1" ] 12 do 13 echo "Processing parameter of: '$1'" 14 if [ ${1:0:1} = '/' ] 15 then 16 tmp=${1:1} # 去掉开头的'/' . . . 17 parameter=${tmp%%=*} # 提取参数名. 18 value=${tmp##*=} # 提取参数值. 19 echo "Parameter: '$parameter', value: '$value'" 20 eval $parameter=$value 21 fi 22 shift 23 done 24 } 25 26 # 把所有选项传给函数getopt_simple(). 27 getopt_simple $* 28 29 echo "test is '$test'" 30 echo "test2 is '$test2'" 31 32 exit 0 33 34 --- 35 36 sh getopt_example.sh /test=value1 /test2=value2 37 38 Parameters are '/test=value1 /test2=value2' 39 Processing parameter of: '/test=value1' 40 Parameter: 'test', value: 'value1' 41 Processing parameter of: '/test2=value2' 42 Parameter: 'test2', value: 'value2' 43 test is 'value1' 44 test2 is 'value2'</PRE></FONT></TD></TR></TABLE><HR></DIV></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B>子串替换</B></P><DL><DT>${string/substring/replacement}</DT><DD><P>使用<TTCLASS="REPLACEABLE"><I>$replacement</I></TT>来替换第一个匹配的<TTCLASS="REPLACEABLE"><I>$substring</I></TT>.</P></DD><DT>${string//substring/replacement}</DT><DD><P>使用<TTCLASS="REPLACEABLE"><I>$replacement</I></TT>来替换所有匹配的<TTCLASS="REPLACEABLE"><I>$substring</I></TT>.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 stringZ=abcABC123ABCabc 2 3 echo ${stringZ/abc/xyz} # xyzABC123ABCabc 4 # 使用'xyz'来替换第一个匹配的'abc'. 5 6 echo ${stringZ//abc/xyz} # xyzABC123ABCxyz 7 # 用'xyz'来替换所有匹配的'abc'.</PRE></FONT></TD></TR></TABLE> </P></DD><DT>${string/#substring/replacement}</DT><DD><P>如果<TTCLASS="REPLACEABLE"><I>$substring</I></TT>匹配<TTCLASS="REPLACEABLE"><I>$string</I></TT>的<EM>开头部分</EM>, 那么就用<TTCLASS="REPLACEABLE"><I>$replacement</I></TT>来替换<TTCLASS="REPLACEABLE"><I>$substring</I></TT>.</P></DD><DT>${string/%substring/replacement}</DT><DD><P>如果<TTCLASS="REPLACEABLE"><I>$substring</I></TT>匹配<TTCLASS="REPLACEABLE"><I>$string</I></TT>的<EM>结尾部分</EM>, 那么就用<TTCLASS="REPLACEABLE"><I>$replacement</I></TT>来替换<TTCLASS="REPLACEABLE"><I>$substring</I></TT>.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 stringZ=abcABC123ABCabc 2 3 echo ${stringZ/#abc/XYZ} # XYZABC123ABCabc 4 # 用'XYZ'替换开头的'abc'. 5 6 echo ${stringZ/%abc/XYZ} # abcABC123ABCXYZ 7 # 用'XYZ'替换结尾的'abc'.</PRE></FONT></TD></TR></TABLE> </P></DD></DL></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AWKSTRINGMANIP">9.2.1. 使用awk来处理字符串</A></H2><P>Bash脚本也可以调用<AHREF="awk.html#AWKREF">awk</A>的字符串操作功能来代替它自己内建的字符串操作. </P><DIVCLASS="EXAMPLE"><HR><ANAME="SUBSTRINGEX"></A><P><B>例子 9-14. 提取字符串的另一种方法</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # substring-extraction.sh 3 4 String=23skidoo1 5 # 012345678 Bash 6 # 123456789 awk 7 # 注意不同的字符串索引系统: 8 # Bash的第一个字符是从'0'开始记录的. 9 # Awk的第一个字符是从'1'开始记录的. 10 11 echo ${String:2:4} # 位置 3 (0-1-2), 4 个字符长 12 # skid 13 14 # awk中等价于${string:pos:length}的命令是substr(string,pos,length). 15 echo | awk ' 16 { print substr("'"${String}"'",3,4) # skid 17 } 18 ' 19 # 使用一个空的"echo"通过管道传递给awk一个假的输入, 20 #+ 这样就不必提供一个文件名给awk. 21 22 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="STRFDISC">9.2.2. 更深入的讨论</A></H2><P>如果想了解关于在脚本中使用字符串的更多细节, 请参考<AHREF="parameter-substitution.html">Section 9.3</A>和<AHREF="moreadv.html#EXPRREF">expr</A>命令列表的<AHREF="moreadv.html#EXPEXTRSUB">相关章节</A>. 相关脚本的例子, 参见: <P></P><OLTYPE="1"><LI><P><AHREF="moreadv.html#EX45">例子 12-9</A></P></LI><LI><P><AHREF="parameter-substitution.html#LENGTH">例子 9-17</A></P></LI><LI><P><AHREF="parameter-substitution.html#PATTMATCHING">例子 9-18</A></P></LI><LI><P><AHREF="parameter-substitution.html#RFE">例子 9-19</A></P></LI><LI><P><AHREF="parameter-substitution.html#VARMATCH">例子 9-21</A></P></LI></OL> </P></DIV></DIV><H3CLASS="FOOTNOTES">注意事项</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN4649"HREF="string-manipulation.html#AEN4649"><SPANCLASS="footnote">[1]</SPAN></A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>这适用于命令行参数或<AHREF="functions.html#FUNCTIONREF">函数</A>参数. </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="internalvariables.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="parameter-substitution.html"ACCESSKEY="N">下一页</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">内部变量</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="variables2.html"ACCESSKEY="U">上一级</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">参数替换</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?