⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basics-reviewed.bash

📁 BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版
💻 BASH
📖 第 1 页 / 共 2 页
字号:
#  The Extended-Syntax string operations can be applied to all#+ elements of an array.####  This may be thought of as a For-Each operation on a vector of strings.####  Parameters are similar to an array.#  The initialization of a parameter array for a script#+ and a parameter array for a function only differ#+ in the initialization of ${0}, which never changes its setting.####  Subscript zero of the script's parameter array contains#+ the name of the script.####  Subscript zero of a function's parameter array DOES NOT contain#+ the name of the function.#  The name of the current function is accessed by the $FUNCNAME variable.####  A quick, review list follows (quick, not short).echoecho '- - Test (but not change) - -'echo '- null reference -'echo -n ${VarNull-'NotSet'}' '          # NotSetecho ${VarNull}                         # NewLine onlyecho -n ${VarNull:-'NotSet'}' '         # NotSetecho ${VarNull}                         # Newline onlyecho '- null contents -'echo -n ${VarEmpty-'Empty'}' '          # Only the spaceecho ${VarEmpty}                        # Newline onlyecho -n ${VarEmpty:-'Empty'}' '         # Emptyecho ${VarEmpty}                        # Newline onlyecho '- contents -'echo ${VarSomething-'Content'}          # Literalecho ${VarSomething:-'Content'}         # Literalecho '- Sparse Array -'echo ${ArrayVar[@]-'not set'}# ASCII-Art time# State     Y==yes, N==no#           -       :-# Unset     Y       Y       ${# ... } == 0# Empty     N       Y       ${# ... } == 0# Contents  N       N       ${# ... } > 0#  Either the first and/or the second part of the tests#+ may be a command or a function invocation string.echoecho '- - Test 1 for undefined - -'declare -i t_decT() {    t=$t-1}# Null reference, set: t == -1t=${#VarNull}                           # Results in zero.${VarNull- _decT }                      # Function executes, t now -1.echo $t# Null contents, set: t == 0t=${#VarEmpty}                          # Results in zero.${VarEmpty- _decT }                     # _decT function NOT executed.echo $t# Contents, set: t == number of non-null charactersVarSomething='_simple'                  # Set to valid function name.t=${#VarSomething}                      # non-zero length${VarSomething- _decT }                 # Function _simple executed.echo $t                                 # Note the Append-To action.# Exercise: clean up that example.unset tunset _decTVarSomething=Literalechoecho '- - Test and Change - -'echo '- Assignment if null reference -'echo -n ${VarNull='NotSet'}' '          # NotSet NotSetecho ${VarNull}unset VarNullecho '- Assignment if null reference -'echo -n ${VarNull:='NotSet'}' '         # NotSet NotSetecho ${VarNull}unset VarNullecho '- No assignment if null contents -'echo -n ${VarEmpty='Empty'}' '          # Space onlyecho ${VarEmpty}VarEmpty=''echo '- Assignment if null contents -'echo -n ${VarEmpty:='Empty'}' '         # Empty Emptyecho ${VarEmpty}VarEmpty=''echo '- No change if already has contents -'echo ${VarSomething='Content'}          # Literalecho ${VarSomething:='Content'}         # Literal# "Subscript sparse" Bash-Arrays####  Bash-Arrays are subscript packed, beginning with#+ subscript zero unless otherwise specified.####  The initialization of ArrayVar was one way#+ to "otherwise specify".  Here is the other way:###echodeclare -a ArraySparseArraySparse=( [1]=one [2]='' [4]='four' )# [0]=null reference, [2]=null content, [3]=null referenceecho '- - Array-Sparse List - -'# Within double-quotes, default IFS, Glob-PatternIFS=$'\x20'$'\x09'$'\x0A'printf %q "${ArraySparse[*]}"echo#  Note that the output does not distinguish between "null content"#+ and "null reference".#  Both print as escaped whitespace.####  Note also that the output does NOT contain escaped whitespace#+ for the "null reference(s)" prior to the first defined element.#### This behavior of 2.04, 2.05a and 2.05b has been reported#+ and may change in a future version of Bash.#  To output a sparse array and maintain the [subscript]=value#+ relationship without change requires a bit of programming.#  One possible code fragment:#### local l=${#ArraySparse[@]}        # Count of defined elements# local f=0                         # Count of found subscripts# local i=0                         # Subscript to test(                                   # Anonymous in-line function    for (( l=${#ArraySparse[@]}, f = 0, i = 0 ; f < l ; i++ ))    do        # 'if defined then...'        ${ArraySparse[$i]+ eval echo '\ ['$i']='${ArraySparse[$i]} ; (( f++ )) }    done)# The reader coming upon the above code fragment cold#+ might want to review "command lists" and "multiple commands on a line"#+ in the text of the foregoing "Advanced Bash Scripting Guide."####  Note:#  The "read -a array_name" version of the "read" command#+ begins filling array_name at subscript zero.#  ArraySparse does not define a value at subscript zero.####  The user needing to read/write a sparse array to either#+ external storage or a communications socket must invent#+ a read/write code pair suitable for their purpose.#### Exercise: clean it up.unset ArraySparseechoecho '- - Conditional alternate (But not change)- -'echo '- No alternate if null reference -'echo -n ${VarNull+'NotSet'}' 'echo ${VarNull}unset VarNullecho '- No alternate if null reference -'echo -n ${VarNull:+'NotSet'}' 'echo ${VarNull}unset VarNullecho '- Alternate if null contents -'echo -n ${VarEmpty+'Empty'}' '              # Emptyecho ${VarEmpty}VarEmpty=''echo '- No alternate if null contents -'echo -n ${VarEmpty:+'Empty'}' '             # Space onlyecho ${VarEmpty}VarEmpty=''echo '- Alternate if already has contents -'# Alternate literalecho -n ${VarSomething+'Content'}' '        # Content Literalecho ${VarSomething}# Invoke functionecho -n ${VarSomething:+ $(_simple) }' '    # SimpleFunc Literalecho ${VarSomething}echoecho '- - Sparse Array - -'echo ${ArrayVar[@]+'Empty'}                 # An array of 'Empty'(ies)echoecho '- - Test 2 for undefined - -'declare -i t_incT() {    t=$t+1}#  Note:#  This is the same test used in the sparse array#+ listing code fragment.# Null reference, set: t == -1t=${#VarNull}-1                     # Results in minus-one.${VarNull+ _incT }                  # Does not execute.echo $t' Null reference'# Null contents, set: t == 0t=${#VarEmpty}-1                    # Results in minus-one.${VarEmpty+ _incT }                 # Executes.echo $t'  Null content'# Contents, set: t == (number of non-null characters)t=${#VarSomething}-1                # non-null length minus-one${VarSomething+ _incT }             # Executes.echo $t'  Contents'# Exercise: clean up that example.unset tunset _incT# ${name?err_msg} ${name:?err_msg}#  These follow the same rules but always exit afterwards#+ if an action is specified following the question mark.#  The action following the question mark may be a literal#+ or a function result.####  ${name?} ${name:?} are test-only, the return can be tested.# Element operations# ------------------echoecho '- - Trailing sub-element selection - -'#  Strings, Arrays and Positional parameters#  Call this script with multiple arguments#+ to see the parameter selections.echo '- All -'echo ${VarSomething:0}              # all non-null charactersecho ${ArrayVar[@]:0}               # all elements with contentecho ${@:0}                         # all parameters with content;                                    # ignoring parameter[0]echoecho '- All after -'echo ${VarSomething:1}              # all non-null after character[0]echo ${ArrayVar[@]:1}               # all after element[0] with contentecho ${@:2}                         # all after param[1] with contentechoecho '- Range after -'echo ${VarSomething:4:3}            # ral                                    # Three characters after                                    # character[3]echo '- Sparse array gotch -'echo ${ArrayVar[@]:1:2}     #  four - The only element with content.                            #  Two elements after (if that many exist).                            #  the FIRST WITH CONTENTS                            #+ (the FIRST WITH  CONTENTS is being                            #+ considered as if it                            #+ were subscript zero).#  Executed as if Bash considers ONLY array elements with CONTENT#  printf %q "${ArrayVar[@]:0:3}"    # Try this one#  In versions 2.04, 2.05a and 2.05b,#+ Bash does not handle sparse arrays as expected using this notation.##  The current Bash maintainer, Chet Ramey, has corrected this#+ for an upcoming version of Bash.echo '- Non-sparse array -'echo ${@:2:2}               # Two parameters following parameter[1]# New victims for string vector examples:stringZ=abcABC123ABCabcarrayZ=( abcabc ABCABC 123123 ABCABC abcabc )sparseZ=( [1]='abcabc' [3]='ABCABC' [4]='' [5]='123123' )echoecho ' - - Victim string - -'$stringZ'- - 'echo ' - - Victim array - -'${arrayZ[@]}'- - 'echo ' - - Sparse array - -'${sparseZ[@]}'- - 'echo ' - [0]==null ref, [2]==null ref, [4]==null content - 'echo ' - [1]=abcabc [3]=ABCABC [5]=123123 - 'echo ' - non-null-reference count: '${#sparseZ[@]}' elements'echoecho '- - Prefix sub-element removal - -'echo '- - Glob-Pattern match must include the first character. - -'echo '- - Glob-Pattern may be a literal or a function result. - -'echo# Function returning a simple, Literal, Glob-Pattern_abc() {    echo -n 'abc'}echo '- Shortest prefix -'echo ${stringZ#123}                 # Unchanged (not a prefix).echo ${stringZ#$(_abc)}             # ABC123ABCabcecho ${arrayZ[@]#abc}               # Applied to each element.# Fixed by Chet Ramey for an upcoming version of Bash.# echo ${sparseZ[@]#abc}            # Version-2.05b core dumps.# The -it would be nice- First-Subscript-Of# echo ${#sparseZ[@]#*}             # This is NOT valid Bash.echoecho '- Longest prefix -'echo ${stringZ##1*3}                # Unchanged (not a prefix)echo ${stringZ##a*C}                # abcecho ${arrayZ[@]##a*c}              # ABCABC 123123 ABCABC# Fixed by Chet Ramey for an upcoming version of Bash# echo ${sparseZ[@]##a*c}           # Version-2.05b core dumps.echoecho '- - Suffix sub-element removal - -'echo '- - Glob-Pattern match must include the last character. - -'echo '- - Glob-Pattern may be a literal or a function result. - -'echoecho '- Shortest suffix -'echo ${stringZ%1*3}                 # Unchanged (not a suffix).echo ${stringZ%$(_abc)}             # abcABC123ABCecho ${arrayZ[@]%abc}               # Applied to each element.# Fixed by Chet Ramey for an upcoming version of Bash.# echo ${sparseZ[@]%abc}            # Version-2.05b core dumps.# The -it would be nice- Last-Subscript-Of# echo ${#sparseZ[@]%*}             # This is NOT valid Bash.echoecho '- Longest suffix -'echo ${stringZ%%1*3}                # Unchanged (not a suffix)echo ${stringZ%%b*c}                # aecho ${arrayZ[@]%%b*c}              # a ABCABC 123123 ABCABC a# Fixed by Chet Ramey for an upcoming version of Bash.# echo ${sparseZ[@]%%b*c}           # Version-2.05b core dumps.echoecho '- - Sub-element replacement - -'echo '- - Sub-element at any location in string. - -'echo '- - First specification is a Glob-Pattern - -'echo '- - Glob-Pattern may be a literal or Glob-Pattern function result. - -'echo '- - Second specification may be a literal or function result. - -'echo '- - Second specification may be unspecified. Pronounce that'echo '    as: Replace-With-Nothing (Delete) - -'echo# Function returning a simple, Literal, Glob-Pattern_123() {    echo -n '123'}echo '- Replace first occurrence -'echo ${stringZ/$(_123)/999}         # Changed (123 is a component).echo ${stringZ/ABC/xyz}             # xyzABC123ABCabcecho ${arrayZ[@]/ABC/xyz}           # Applied to each element.echo ${sparseZ[@]/ABC/xyz}          # Works as expected.echoecho '- Delete first occurrence -'echo ${stringZ/$(_123)/}echo ${stringZ/ABC/}echo ${arrayZ[@]/ABC/}echo ${sparseZ[@]/ABC/}#  The replacement need not be a literal,#+ since the result of a function invocation is allowed.#  This is general to all forms of replacement.echoecho '- Replace first occurrence with Result-Of -'echo ${stringZ/$(_123)/$(_simple)}  # Works as expected.echo ${arrayZ[@]/ca/$(_simple)}     # Applied to each element.echo ${sparseZ[@]/ca/$(_simple)}    # Works as expected.echoecho '- Replace all occurrences -'echo ${stringZ//[b2]/X}             # X-out b's and 2'secho ${stringZ//abc/xyz}            # xyzABC123ABCxyzecho ${arrayZ[@]//abc/xyz}          # Applied to each element.echo ${sparseZ[@]//abc/xyz}         # Works as expected.echoecho '- Delete all occurrences -'echo ${stringZ//[b2]/}echo ${stringZ//abc/}echo ${arrayZ[@]//abc/}echo ${sparseZ[@]//abc/}echoecho '- - Prefix sub-element replacement - -'echo '- - Match must include the first character. - -'echoecho '- Replace prefix occurrences -'echo ${stringZ/#[b2]/X}             # Unchanged (neither is a prefix).echo ${stringZ/#$(_abc)/XYZ}        # XYZABC123ABCabcecho ${arrayZ[@]/#abc/XYZ}          # Applied to each element.echo ${sparseZ[@]/#abc/XYZ}         # Works as expected.echoecho '- Delete prefix occurrences -'echo ${stringZ/#[b2]/}echo ${stringZ/#$(_abc)/}echo ${arrayZ[@]/#abc/}echo ${sparseZ[@]/#abc/}echoecho '- - Suffix sub-element replacement - -'echo '- - Match must include the last character. - -'echoecho '- Replace suffix occurrences -'echo ${stringZ/%[b2]/X}             # Unchanged (neither is a suffix).echo ${stringZ/%$(_abc)/XYZ}        # abcABC123ABCXYZecho ${arrayZ[@]/%abc/XYZ}          # Applied to each element.echo ${sparseZ[@]/%abc/XYZ}         # Works as expected.echoecho '- Delete suffix occurrences -'echo ${stringZ/%[b2]/}echo ${stringZ/%$(_abc)/}echo ${arrayZ[@]/%abc/}echo ${sparseZ[@]/%abc/}echoecho '- - Special cases of null Glob-Pattern - -'echoecho '- Prefix all -'# null substring pattern means 'prefix'echo ${stringZ/#/NEW}               # NEWabcABC123ABCabcecho ${arrayZ[@]/#/NEW}             # Applied to each element.echo ${sparseZ[@]/#/NEW}            # Applied to null-content also.                                    # That seems reasonable.echoecho '- Suffix all -'# null substring pattern means 'suffix'echo ${stringZ/%/NEW}               # abcABC123ABCabcNEWecho ${arrayZ[@]/%/NEW}             # Applied to each element.echo ${sparseZ[@]/%/NEW}            # Applied to null-content also.                                    # That seems reasonable.echoecho '- - Special case For-Each Glob-Pattern - -'echo '- - - - This is a nice-to-have dream - - - -'echo_GenFunc() {    echo -n ${0}                    # Illustration only.    # Actually, that would be an arbitrary computation.}# All occurrences, matching the AnyThing pattern.# Currently //*/ does not match null-content nor null-reference.# /#/ and /%/ does match null-content but not null-reference.echo ${sparseZ[@]//*/$(_GenFunc)}#  A possible syntax would be to make#+ the parameter notation used within this construct mean:#   ${1} - The full element#   ${2} - The prefix, if any, to the matched sub-element#   ${3} - The matched sub-element#   ${4} - The suffix, if any, to the matched sub-element## echo ${sparseZ[@]//*/$(_GenFunc ${3})}   # Same as ${1} here.# Perhaps it will be implemented in a future version of Bash.exit 0

⌨️ 快捷键说明

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