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 stringZ=abcABC123ABCabc 2 3 echo ${#stringZ} # 15 4 echo `expr length $stringZ` # 15 5 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 #!/bin/bash 2 # paragraph-space.sh 3 4 # 在一个单倍行距的文本文件中插入空行. 5 # Usage: $0 <FILENAME 6 7 MINLEN=45 # 可能需要修改这个值. 8 # 假定行的长度小于$MINLEN所指定的长度的时候 9 #+ 才认为此段结束. 10 11 while read line # 提供和输入文件一样多的行... 12 do 13 echo "$line" # 输入所读入的行本身. 14 15 len=${#line} 16 if [ "$len" -lt "$MINLEN" ] 17 then echo # 在短行(译者注: 也就是小于$MINLEN个字符的行)后面添加一个空行. 18 fi 19 done 20 21 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> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 stringZ=abcABC123ABCabc 2 # |------| 3 4 echo `expr match "$stringZ" 'abc[A-Z]*.2'` # 8 5 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 stringZ=abcABC123ABCabc 2 echo `expr index "$stringZ" C12` # 6 3 # C 字符的位置. 4 5 echo `expr index "$stringZ" 1c` # 3 6 # '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 stringZ=abcABC123ABCabc 2 # 0123456789..... 3 # 0-based indexing. 4 5 echo ${stringZ:0} # abcABC123ABCabc 6 echo ${stringZ:1} # bcABC123ABCabc 7 echo ${stringZ:7} # 23ABCabc 8 9 echo ${stringZ:7:3} # 23A 10 # 提取子串长度为3. 11 12 13 14 # 能不能从字符串的右边(也就是结尾)部分开始提取子串? 15 16 echo ${stringZ:-4} # abcABC123ABCabc 17 # 默认是提取整个字符串, 就象${parameter:-default}一样. 18 # 然而 . . . 19 20 echo ${stringZ:(-4)} # Cabc 21 echo ${stringZ: -4} # Cabc 22 # 这样, 它就可以工作了. 23 # 使用圆括号或者添加一个空格可以"转义"这个位置参数. 24 25 # 感谢, 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 echo ${*:2} # 打印出第2个和后边所有的位置参数. 2 echo ${@:2} # 同上. 3 4 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 stringZ=abcABC123ABCabc 2 # 123456789...... 3 # 以1开始计算. 4 5 echo `expr substr $stringZ 1 2` # ab 6 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 stringZ=abcABC123ABCabc 2 # ======= 3 4 echo `expr match "$stringZ" '\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1 5 echo `expr "$stringZ" : '\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1 6 echo `expr "$stringZ" : '\(.......\)'` # abcABC1 7 # 上边的每个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 stringZ=abcABC123ABCabc 2 # ====== 3 4 echo `expr match "$stringZ" '.*\([A-C][A-C][A-C][a-c]*\)'` # ABCabc 5 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 + -
显示快捷键?