string-manipulation.html

来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 1,376 行 · 第 1/2 页

HTML
1,376
字号
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><HTML><HEAD><TITLE>操作字符串</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINKREL="HOME"TITLE="高级Bash脚本编程指南"HREF="index.html"><LINKREL="UP"TITLE="变量重游"HREF="variables2.html"><LINKREL="PREVIOUS"TITLE="内部变量"HREF="internalvariables.html"><LINKREL="NEXT"TITLE="参数替换"HREF="parameter-substitution.html"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">高级Bash脚本编程指南: 一本深入学习shell脚本艺术的书籍</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="internalvariables.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">9. 变量重游</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="parameter-substitution.html"ACCESSKEY="N">下一页</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="STRING-MANIPULATION">9.2. 操作字符串</A></H1><P><ANAME="STRINGMANIP"></A></P><P>Bash所支持的字符串操作的数量多的令人惊讶. 	      但是不幸的是, 这些工具缺乏统一的标准.		  一些是<AHREF="parameter-substitution.html#PARAMSUBREF">参数替换</A>的子集, 		  而另外一些则受到UNIX <AHREF="moreadv.html#EXPRREF">expr</A>命令的影响. 		  这就导致了命令语法的不一致, 还会引起冗余的功能, 但是这些并没有引起混乱. </P><P></P><DIVCLASS="VARIABLELIST"><P><B>字符串长度</B></P><DL><DT>${#string}</DT><DD><P></P></DD><DT>expr length $string</DT><DD><P></P></DD><DT>expr "$string" : '.*'</DT><DD><P>	  <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;stringZ=abcABC123ABCabc  2&nbsp;  3&nbsp;echo ${#stringZ}                 # 15  4&nbsp;echo `expr length $stringZ`      # 15  5&nbsp;echo `expr "$stringZ" : '.*'`    # 15</PRE></FONT></TD></TR></TABLE>	  </P></DD></DL></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="PARAGRAPHSPACE"></A><P><B>例子 9-10. 在一个文本文件的段落之间插入空行</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# paragraph-space.sh  3&nbsp;  4&nbsp;# 在一个单倍行距的文本文件中插入空行.  5&nbsp;# Usage: $0 &#60;FILENAME  6&nbsp;  7&nbsp;MINLEN=45        # 可能需要修改这个值.  8&nbsp;#  假定行的长度小于$MINLEN所指定的长度的时候   9&nbsp;#+ 才认为此段结束. 10&nbsp; 11&nbsp;while read line  # 提供和输入文件一样多的行... 12&nbsp;do 13&nbsp;  echo "$line"   # 输入所读入的行本身. 14&nbsp; 15&nbsp;  len=${#line} 16&nbsp;  if [ "$len" -lt "$MINLEN" ] 17&nbsp;    then echo    # 在短行(译者注: 也就是小于$MINLEN个字符的行)后面添加一个空行. 18&nbsp;  fi   19&nbsp;done 20&nbsp; 21&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B>匹配字符串开头的子串长度</B></P><DL><DT>expr match "$string" '$substring'</DT><DD><P><TTCLASS="REPLACEABLE"><I>$substring</I></TT>是一个<AHREF="regexp.html#REGEXREF">正则表达式</A>.</P></DD><DT>expr "$string" : '$substring'</DT><DD><P><TTCLASS="REPLACEABLE"><I>$substring</I></TT>是一个正则表达式.</P><P>&#13;	  <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;stringZ=abcABC123ABCabc  2&nbsp;#       |------|  3&nbsp;  4&nbsp;echo `expr match "$stringZ" 'abc[A-Z]*.2'`   # 8  5&nbsp;echo `expr "$stringZ" : 'abc[A-Z]*.2'`       # 8</PRE></FONT></TD></TR></TABLE>          </P></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B>索引</B></P><DL><DT>expr index $string $substring</DT><DD><P>在字符串$string中所匹配到的$substring第一次所出现的位置. </P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;stringZ=abcABC123ABCabc  2&nbsp;echo `expr index "$stringZ" C12`             # 6  3&nbsp;                                             # C 字符的位置.  4&nbsp;  5&nbsp;echo `expr index "$stringZ" 1c`              # 3  6&nbsp;# 'c' (in #3 position) matches before '1'.</PRE></FONT></TD></TR></TABLE></P><P>这与C语言中的<EM>strchr()</EM>函数非常相似. </P></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B>提取子串</B></P><DL><DT>${string:position}</DT><DD><P>在<TTCLASS="REPLACEABLE"><I>$string</I></TT>中从位置<TTCLASS="REPLACEABLE"><I>$position</I></TT>开始提取子串.</P><P>如果<CODECLASS="VARNAME">$string</CODE>是<SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">*</SPAN>"</SPAN>或者<SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">@</SPAN>"</SPAN>, 		  那么将会提取从位置<CODECLASS="VARNAME">$position</CODE>开始的<AHREF="internalvariables.html#POSPARAMREF">位置参数</A>. 	       <ANAME="AEN4649"HREF="#FTN.AEN4649"><SPANCLASS="footnote">[1]</SPAN></A></P></DD><DT>${string:position:length}</DT><DD><P>在<TTCLASS="REPLACEABLE"><I>$string</I></TT>中从位置<TTCLASS="REPLACEABLE"><I>$position</I></TT>开始提取<TTCLASS="REPLACEABLE"><I>$length</I></TT>长度的子串.</P><P>	  <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;stringZ=abcABC123ABCabc  2&nbsp;#       0123456789.....  3&nbsp;#       0-based indexing.  4&nbsp;  5&nbsp;echo ${stringZ:0}                            # abcABC123ABCabc  6&nbsp;echo ${stringZ:1}                            # bcABC123ABCabc  7&nbsp;echo ${stringZ:7}                            # 23ABCabc  8&nbsp;  9&nbsp;echo ${stringZ:7:3}                          # 23A 10&nbsp;                                             # 提取子串长度为3. 11&nbsp; 12&nbsp; 13&nbsp; 14&nbsp;# 能不能从字符串的右边(也就是结尾)部分开始提取子串?  15&nbsp;     16&nbsp;echo ${stringZ:-4}                           # abcABC123ABCabc 17&nbsp;# 默认是提取整个字符串, 就象${parameter:-default}一样. 18&nbsp;# 然而 . . . 19&nbsp; 20&nbsp;echo ${stringZ:(-4)}                         # Cabc  21&nbsp;echo ${stringZ: -4}                          # Cabc 22&nbsp;# 这样, 它就可以工作了. 23&nbsp;# 使用圆括号或者添加一个空格可以"转义"这个位置参数. 24&nbsp; 25&nbsp;# 感谢, Dan Jacobson, 指出这点.</PRE></FONT></TD></TR></TABLE>	  </P><P>如果<CODECLASS="VARNAME">$string</CODE>参数是<SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">*</SPAN>"</SPAN>或<SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">@</SPAN>"</SPAN>, 		  那么将会从<CODECLASS="VARNAME">$position</CODE>位置开始提取<CODECLASS="VARNAME">$length</CODE>个位置参数, 		  但是由于可能没有<CODECLASS="VARNAME">$length</CODE>个位置参数了, 		  那么就有几个位置参数就提取几个位置参数. </P><P>	  <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;echo ${*:2}          # 打印出第2个和后边所有的位置参数.  2&nbsp;echo ${@:2}          # 同上.  3&nbsp;  4&nbsp;echo ${*:2:3}        # 从第2个开始, 连续打印3个位置参数. </PRE></FONT></TD></TR></TABLE>	  </P></DD><DT>expr substr $string $position $length</DT><DD><P>在<TTCLASS="REPLACEABLE"><I>$string</I></TT>中从<TTCLASS="REPLACEABLE"><I>$position</I></TT>开始提取<TTCLASS="REPLACEABLE"><I>$length</I></TT>长度的子串.</P><P>	  <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;stringZ=abcABC123ABCabc  2&nbsp;#       123456789......  3&nbsp;#       以1开始计算.  4&nbsp;  5&nbsp;echo `expr substr $stringZ 1 2`              # ab  6&nbsp;echo `expr substr $stringZ 4 3`              # ABC</PRE></FONT></TD></TR></TABLE>          </P><P><ANAME="EXPRPAREN"></A></P></DD><DT>expr match "$string" '\($substring\)'</DT><DD><P>从<TTCLASS="REPLACEABLE"><I>$string</I></TT>的开始位置提取<TTCLASS="REPLACEABLE"><I>$substring</I></TT>,	    <TTCLASS="REPLACEABLE"><I>$substring</I></TT>是<AHREF="regexp.html#REGEXREF">正则表达式</A>.</P></DD><DT>expr "$string" : '\($substring\)'</DT><DD><P>从<TTCLASS="REPLACEABLE"><I>$string</I></TT>的开始位置提取<TTCLASS="REPLACEABLE"><I>$substring</I></TT>,	    <TTCLASS="REPLACEABLE"><I>$substring</I></TT>是正则表达式. </P><P>	    <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;stringZ=abcABC123ABCabc  2&nbsp;#       =======	      3&nbsp;  4&nbsp;echo `expr match "$stringZ" '\(.[b-c]*[A-Z]..[0-9]\)'`   # abcABC1  5&nbsp;echo `expr "$stringZ" : '\(.[b-c]*[A-Z]..[0-9]\)'`       # abcABC1  6&nbsp;echo `expr "$stringZ" : '\(.......\)'`                   # abcABC1  7&nbsp;# 上边的每个echo都打印出相同的结果. </PRE></FONT></TD></TR></TABLE>	    </P></DD><DT>expr match "$string" '.*\($substring\)'</DT><DD><P>从<TTCLASS="REPLACEABLE"><I>$string</I></TT>的<EM>结尾</EM>提取<TTCLASS="REPLACEABLE"><I>$substring</I></TT>, 	    <TTCLASS="REPLACEABLE"><I>$substring</I></TT>是正则表达式. </P></DD><DT>expr "$string" : '.*\($substring\)'</DT><DD><P>从<TTCLASS="REPLACEABLE"><I>$string</I></TT>的<EM>结尾</EM>提取<TTCLASS="REPLACEABLE"><I>$substring</I></TT>, 	    <TTCLASS="REPLACEABLE"><I>$substring</I></TT>是正则表达式. </P><P>	    <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;stringZ=abcABC123ABCabc  2&nbsp;#                ======  3&nbsp;  4&nbsp;echo `expr match "$stringZ" '.*\([A-C][A-C][A-C][a-c]*\)'`    # ABCabc  5&nbsp;echo `expr "$stringZ" : '.*\(......\)'`                       # ABCabc</PRE></FONT></TD></TR></TABLE>	    </P></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B>子串削除</B></P><DL><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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?