📄 string-manipulation.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Manipulating Strings</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Variables Revisited"HREF="variables2.html"><LINKREL="PREVIOUS"TITLE="Variables Revisited"HREF="variables2.html"><LINKREL="NEXT"TITLE="Parameter Substitution"HREF="parameter-substitution.html"><METAHTTP-EQUIV="Content-Style-Type"CONTENT="text/css"><LINKREL="stylesheet"HREF="common/kde-common.css"TYPE="text/css"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=iso-8859-1"><METAHTTP-EQUIV="Content-Language"CONTENT="en"><LINKREL="stylesheet"HREF="common/kde-localised.css"TYPE="text/css"TITLE="KDE-English"><LINKREL="stylesheet"HREF="common/kde-default.css"TYPE="text/css"TITLE="KDE-Default"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#AA0000"VLINK="#AA0055"ALINK="#AA0000"STYLE="font-family: sans-serif;"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="variables2.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 9. Variables Revisited</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="parameter-substitution.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="STRING-MANIPULATION"></A>9.2. Manipulating Strings</H1><P><ANAME="STRINGMANIP"></A></P><P>Bash supports a surprising number of string manipulation operations. Unfortunately, these tools lack a unified focus. Some are a subset of <AHREF="parameter-substitution.html#PARAMSUBREF">parameter substitution</A>, and others fall under the functionality of the UNIX <AHREF="moreadv.html#EXPRREF">expr</A> command. This results in inconsistent command syntax and overlap of functionality, not to mention confusion.</P><DIVCLASS="VARIABLELIST"><P><B>String Length</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><PRECLASS="PROGRAMLISTING"> 1 stringZ=abcABC123ABCabc 2 3 echo ${#stringZ} # 15 4 echo `expr length $stringZ` # 15 5 echo `expr "$stringZ" : '.*'` # 15</PRE></TD></TR></TABLE> </P></DD></DL></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="PARAGRAPHSPACE"></A><P><B>Example 9-10. Inserting a blank line between paragraphs in a text file</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # paragraph-space.sh 3 4 # Inserts a blank line between paragraphs of a single-spaced text file. 5 # Usage: $0 <FILENAME 6 7 MINLEN=45 # May need to change this value. 8 # Assume lines shorter than $MINLEN characters 9 #+ terminate a paragraph. 10 11 while read line # For as many lines as the input file has... 12 do 13 echo "$line" # Output the line itself. 14 15 len=${#line} 16 if [ "$len" -lt "$MINLEN" ] 17 then echo # Add a blank line after short line. 18 fi 19 done 20 21 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="VARIABLELIST"><P><B>Length of Matching Substring at Beginning of String</B></P><DL><DT><ANAME="EXPRMATCH"></A>expr match "$string" '$substring'</DT><DD><P><TTCLASS="REPLACEABLE"><I>$substring</I></TT> is a <AHREF="regexp.html#REGEXREF">regular expression</A>.</P></DD><DT>expr "$string" : '$substring'</DT><DD><P><TTCLASS="REPLACEABLE"><I>$substring</I></TT> is a regular expression.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><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></TD></TR></TABLE> </P></DD></DL></DIV><DIVCLASS="VARIABLELIST"><P><B>Index</B></P><DL><DT><ANAME="SUBSTRINGINDEX2"></A>expr index $string $substring</DT><DD><P>Numerical position in $string of first character in $substring that matches.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 stringZ=abcABC123ABCabc 2 echo `expr index "$stringZ" C12` # 6 3 # C position. 4 5 echo `expr index "$stringZ" 1c` # 3 6 # 'c' (in #3 position) matches before '1'.</PRE></TD></TR></TABLE></P><P>This is the near equivalent of <ICLASS="FIRSTTERM">strchr()</I> in <ICLASS="FIRSTTERM">C</I>.</P></DD></DL></DIV><DIVCLASS="VARIABLELIST"><P><B>Substring Extraction</B></P><DL><DT><ANAME="SUBSTREXTR01"></A>${string:position}</DT><DD><P>Extracts substring from <TTCLASS="REPLACEABLE"><I>$string</I></TT> at <TTCLASS="REPLACEABLE"><I>$position</I></TT>.</P><P>If the <TTCLASS="VARNAME">$string</TT> parameter is <SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">*</SPAN>"</SPAN> or <SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">@</SPAN>"</SPAN>, then this extracts the <AHREF="variables2.html#POSPARAMREF">positional parameters</A>, <ANAME="AEN5008"HREF="#FTN.AEN5008">[1]</A> starting at <TTCLASS="VARNAME">$position</TT>.</P></DD><DT><ANAME="SUBSTREXTR02"></A>${string:position:length}</DT><DD><P>Extracts <TTCLASS="REPLACEABLE"><I>$length</I></TT> characters of substring from <TTCLASS="REPLACEABLE"><I>$string</I></TT> at <TTCLASS="REPLACEABLE"><I>$position</I></TT>.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><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 # Three characters of substring. 11 12 13 14 # Is it possible to index from the right end of the string? 15 16 echo ${stringZ:-4} # abcABC123ABCabc 17 # Defaults to full string, as in ${parameter:-default}. 18 # However . . . 19 20 echo ${stringZ:(-4)} # Cabc 21 echo ${stringZ: -4} # Cabc 22 # Now, it works. 23 # Parentheses or added space "escape" the position parameter. 24 25 # Thank you, Dan Jacobson, for pointing this out.</PRE></TD></TR></TABLE> </P><P>The <ICLASS="FIRSTTERM">position</I> and <ICLASS="FIRSTTERM">length</I> arguments can be <SPANCLASS="QUOTE">"parameterized,"</SPAN> that is, represented as a variable, rather than as a numerical constant.</P><P><ANAME="RANDSTRING0"></A></P><DIVCLASS="EXAMPLE"><HR><ANAME="RANDSTRING"></A><P><B>Example 9-11. Generating an 8-character <SPANCLASS="QUOTE">"random"</SPAN> string</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # rand-string.sh 3 # Generating an 8-character "random" string. 4 5 if [ "-n $1" ] # If command line argument present, 6 then #+ then set start-string to it. 7 str0="$1" 8 else # Else use PID of script as start-string. 9 str0="$$" 10 fi 11 12 POS=2 # Starting from position 2 in the string. 13 LEN=8 # Extract eight characters. 14 15 str1=$( echo "$str0" | md5sum | md5sum ) 16 # Doubly scramble: ^^^^^^ ^^^^^^ 17 18 randstring="${str1:$POS:$LEN}" 19 # Can parameterize ^^^^ ^^^^ 20 21 echo "$randstring" 22 23 exit $? 24 25 # bozo$ ./rand-string.sh my-password 26 # 1bdd88c4 27 28 # No, this is is not recommended 29 #+ as a method of generating hack-proof passwords.</PRE></TD></TR></TABLE><HR></DIV><P>If the <TTCLASS="VARNAME">$string</TT> parameter is <SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">*</SPAN>"</SPAN> or <SPANCLASS="QUOTE">"<SPANCLASS="TOKEN">@</SPAN>"</SPAN>, then this extracts a maximum of <TTCLASS="VARNAME">$length</TT> positional parameters, starting at <TTCLASS="VARNAME">$position</TT>.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 echo ${*:2} # Echoes second and following positional parameters. 2 echo ${@:2} # Same as above. 3 4 echo ${*:2:3} # Echoes three positional parameters, starting at second.</PRE></TD></TR></TABLE> </P></DD><DT>expr substr $string $position $length</DT><DD><P>Extracts <TTCLASS="REPLACEABLE"><I>$length</I></TT> characters from <TTCLASS="REPLACEABLE"><I>$string</I></TT> starting at <TTCLASS="REPLACEABLE"><I>$position</I></TT>.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 stringZ=abcABC123ABCabc 2 # 123456789...... 3 # 1-based indexing. 4 5 echo `expr substr $stringZ 1 2` # ab 6 echo `expr substr $stringZ 4 3` # ABC</PRE></TD></TR></TABLE> </P><P><ANAME="EXPRPAREN"></A></P></DD><DT>expr match "$string" '\($substring\)'</DT><DD><P>Extracts <TTCLASS="REPLACEABLE"><I>$substring</I></TT> at beginning of <TTCLASS="REPLACEABLE"><I>$string</I></TT>, where <TTCLASS="REPLACEABLE"><I>$substring</I></TT> is a <AHREF="regexp.html#REGEXREF">regular expression</A>.</P></DD><DT>expr "$string" : '\($substring\)'</DT><DD><P>Extracts <TTCLASS="REPLACEABLE"><I>$substring</I></TT> at beginning of <TTCLASS="REPLACEABLE"><I>$string</I></TT>, where <TTCLASS="REPLACEABLE"><I>$substring</I></TT> is a regular expression.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><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 # All of the above forms give an identical result.</PRE></TD></TR></TABLE> </P></DD><DT>expr match "$string" '.*\($substring\)'</DT><DD><P>Extracts <TTCLASS="REPLACEABLE"><I>$substring</I></TT> at <SPANCLASS="emphasis"><ICLASS="EMPHASIS">end</I></SPAN> of <TTCLASS="REPLACEABLE"><I>$string</I></TT>, where <TTCLASS="REPLACEABLE"><I>$substring</I></TT> is a regular expression.</P></DD><DT>expr "$string" : '.*\($substring\)'</DT><DD><P>Extracts <TTCLASS="REPLACEABLE"><I>$substring</I></TT> at <SPANCLASS="emphasis"><ICLASS="EMPHASIS">end</I></SPAN> of <TTCLASS="REPLACEABLE"><I>$string</I></TT>, where <TTCLASS="REPLACEABLE"><I>$substring</I></TT> is a regular expression.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><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></TD></TR></TABLE> </P></DD></DL></DIV><DIVCLASS="VARIABLELIST"><P><B>Substring Removal</B></P><DL><DT>${string#substring}</DT><DD><P>Strips shortest match of <TTCLASS="REPLACEABLE"><I>$substring</I></TT> from <SPANCLASS="emphasis"><ICLASS="EMPHASIS">front</I></SPAN> of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -