contributed-scripts.html
来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 2,144 行 · 第 1/5 页
HTML
2,144 行
61 echo 62 echo "Name = $input_name" 63 64 65 # Change all characters of name input to lowercase. 66 # ------------------------------------------------ 67 name=$( echo $input_name | tr A-Z a-z ) 68 # ------------------------------------------------ 69 # Just in case argument to script is mixed case. 70 71 72 # Prefix of soundex code: first letter of name. 73 # -------------------------------------------- 74 75 76 char_pos=0 # Initialize character position. 77 prefix0=${name:$char_pos:1} 78 prefix=`echo $prefix0 | tr a-z A-Z` 79 # Uppercase 1st letter of soundex. 80 81 let "char_pos += 1" # Bump character position to 2nd letter of name. 82 name1=${name:$char_pos} 83 84 85 # ++++++++++++++++++++++++++ Exception Patch +++++++++++++++++++++++++++++++++ 86 # Now, we run both the input name and the name shifted one char to the right 87 #+ through the value-assigning function. 88 # If we get the same value out, that means that the first two characters 89 #+ of the name have the same value assigned, and that one should cancel. 90 # However, we also need to test whether the first letter of the name 91 #+ is a vowel or 'w' or 'h', because otherwise this would bollix things up. 92 93 char1=`echo $prefix | tr A-Z a-z` # First letter of name, lowercased. 94 95 assign_value $name 96 s1=$value 97 assign_value $name1 98 s2=$value 99 assign_value $char1100 s3=$value101 s3=9$s3 # If first letter of name is a vowel102 #+ or 'w' or 'h',103 #+ then its "value" will be null (unset).104 #+ Therefore, set it to 9, an otherwise105 #+ unused value, which can be tested for.106 107 108 if [[ "$s1" -ne "$s2" || "$s3" -eq 9 ]]109 then110 suffix=$s2111 else 112 suffix=${s2:$char_pos}113 fi 114 # ++++++++++++++++++++++ end Exception Patch +++++++++++++++++++++++++++++++++115 116 117 padding=000 # Use at most 3 zeroes to pad.118 119 120 soun=$prefix$suffix$padding # Pad with zeroes.121 122 MAXLEN=4 # Truncate to maximum of 4 chars.123 soundex=${soun:0:$MAXLEN}124 125 echo "Soundex = $soundex"126 127 echo128 129 # The soundex code is a method of indexing and classifying names130 #+ by grouping together the ones that sound alike.131 # The soundex code for a given name is the first letter of the name,132 #+ followed by a calculated three-number code.133 # Similar sounding names should have almost the same soundex codes.134 135 # Examples:136 # Smith and Smythe both have a "S-530" soundex.137 # Harrison = H-625138 # Hargison = H-622139 # Harriman = H-655140 141 # This works out fairly well in practice, but there are numerous anomalies.142 #143 #144 # The U.S. Census and certain other governmental agencies use soundex,145 # as do genealogical researchers.146 #147 # For more information,148 #+ see the "National Archives and Records Administration home page",149 #+ http://www.nara.gov/genealogy/soundex/soundex.html150 151 152 153 # Exercise:154 # --------155 # Simplify the "Exception Patch" section of this script.156 157 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="LIFESLOW"></A><P><B>例子 A-10. <SPANCLASS="QUOTE">"Game of Life"</SPAN></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # life.sh: "Life in the Slow Lane" 3 # Version 2: Patched by Daniel Albers 4 #+ to allow non-square grids as input. 5 6 # ##################################################################### # 7 # This is the Bash script version of John Conway's "Game of Life". # 8 # "Life" is a simple implementation of cellular automata. # 9 # --------------------------------------------------------------------- # 10 # On a rectangular grid, let each "cell" be either "living" or "dead". # 11 # Designate a living cell with a dot, and a dead one with a blank space.# 12 # Begin with an arbitrarily drawn dot-and-blank grid, # 13 #+ and let this be the starting generation, "generation 0". # 14 # Determine each successive generation by the following rules: # 15 # 1) Each cell has 8 neighbors, the adjoining cells # 16 #+ left, right, top, bottom, and the 4 diagonals. # 17 # 123 # 18 # 4*5 # 19 # 678 # 20 # # 21 # 2) A living cell with either 2 or 3 living neighbors remains alive. # 22 # 3) A dead cell with 3 living neighbors becomes alive (a "birth"). # 23 SURVIVE=2 # 24 BIRTH=3 # 25 # 4) All other cases result in a dead cell for the next generation. # 26 # ##################################################################### # 27 28 29 startfile=gen0 # Read the starting generation from the file "gen0". 30 # Default, if no other file specified when invoking script. 31 # 32 if [ -n "$1" ] # Specify another "generation 0" file. 33 then 34 startfile="$1" 35 fi 36 37 ############################################ 38 # Abort script if "startfile" not specified 39 #+ AND 40 #+ "gen0" not present. 41 42 E_NOSTARTFILE=68 43 44 if [ ! -e "$startfile" ] 45 then 46 echo "Startfile \""$startfile"\" missing!" 47 exit $E_NOSTARTFILE 48 fi 49 ############################################ 50 51 52 ALIVE1=. 53 DEAD1=_ 54 # Represent living and "dead" cells in the start-up file. 55 56 # ---------------------------------------------------------- # 57 # This script uses a 10 x 10 grid (may be increased, 58 #+ but a large grid will will cause very slow execution). 59 ROWS=10 60 COLS=10 61 # Change above two variables to match grid size, if necessary. 62 # ---------------------------------------------------------- # 63 64 GENERATIONS=10 # How many generations to cycle through. 65 # Adjust this upwards, 66 #+ if you have time on your hands. 67 68 NONE_ALIVE=80 # Exit status on premature bailout, 69 #+ if no cells left alive. 70 TRUE=0 71 FALSE=1 72 ALIVE=0 73 DEAD=1 74 75 avar= # Global; holds current generation. 76 generation=0 # Initialize generation count. 77 78 # ================================================================= 79 80 81 let "cells = $ROWS * $COLS" 82 # How many cells. 83 84 declare -a initial # Arrays containing "cells". 85 declare -a current 86 87 display () 88 { 89 90 alive=0 # How many cells "alive" at any given time. 91 # Initially zero. 92 93 declare -a arr 94 arr=( `echo "$1"` ) # Convert passed arg to array. 95 96 element_count=${#arr[*]} 97 98 local i 99 local rowcheck100 101 for ((i=0; i<$element_count; i++))102 do103 104 # Insert newline at end of each row.105 let "rowcheck = $i % COLS"106 if [ "$rowcheck" -eq 0 ]107 then108 echo # Newline.109 echo -n " " # Indent.110 fi 111 112 cell=${arr[i]}113 114 if [ "$cell" = . ]115 then116 let "alive += 1"117 fi 118 119 echo -n "$cell" | sed -e 's/_/ /g'120 # Print out array and change underscores to spaces.121 done 122 123 return124 125 }126 127 IsValid () # Test whether cell coordinate valid.128 {129 130 if [ -z "$1" -o -z "$2" ] # Mandatory arguments missing?131 then132 return $FALSE133 fi134 135 local row136 local lower_limit=0 # Disallow negative coordinate.137 local upper_limit138 local left139 local right140 141 let "upper_limit = $ROWS * $COLS - 1" # Total number of cells.142 143 144 if [ "$1" -lt "$lower_limit" -o "$1" -gt "$upper_limit" ]145 then146 return $FALSE # Out of array bounds.147 fi 148 149 row=$2150 let "left = $row * $COLS" # Left limit.151 let "right = $left + $COLS - 1" # Right limit.152 153 if [ "$1" -lt "$left" -o "$1" -gt "$right" ]154 then155 return $FALSE # Beyond row boundary.156 fi 157 158 return $TRUE # Valid coordinate.159 160 } 161 162 163 IsAlive () # Test whether cell is alive.164 # Takes array, cell number, state of cell as arguments.165 {166 GetCount "$1" $2 # Get alive cell count in neighborhood.167 local nhbd=$?168 169 170 if [ "$nhbd" -eq "$BIRTH" ] # Alive in any case.171 then172 return $ALIVE173 fi174 175 if [ "$3" = "." -a "$nhbd" -eq "$SURVIVE" ]176 then # Alive only if previously alive.177 return $ALIVE178 fi 179 180 return $DEAD # Default.181 182 } 183 184 185 GetCount () # Count live cells in passed cell's neighborhood.186 # Two arguments needed:187 # $1) variable holding array188 # $2) cell number189 {190 local cell_number=$2191 local array192 local top193 local center194 local bottom195 local r196 local row197 local i198 local t_top199 local t_cen200 local t_bot201 local count=0202 local ROW_NHBD=3203 204 array=( `echo "$1"` )205 206 let "top = $cell_number - $COLS - 1" # Set up cell neighborhood.207 let "center = $cell_number - 1"208 let "bottom = $cell_number + $COLS - 1"209 let "r = $cell_number / $COLS"210 211 for ((i=0; i<$ROW_NHBD; i++)) # Traverse from left to right. 212 do213 let "t_top = $top + $i"214 let "t_cen = $center + $i"215 let "t_bot = $bottom + $i"216 217 218 let "row = $r" # Count center row of neighborhood.219 IsValid $t_cen $row # Valid cell position?220 if [ $? -eq "$TRUE" ]221 then222 if [ ${array[$t_cen]} = "$ALIVE1" ] # Is it alive?223 then # Yes?224 let "count += 1" # Increment count.225 fi 226 fi 227 228 let "row = $r - 1" # Count top row. 229 IsValid $t_top $row230 if [ $? -eq "$TRUE" ]231 then232 if [ ${array[$t_top]} = "$ALIVE1" ] 233 then234 let "count += 1"235 fi 236 fi 237 238 let "row = $r + 1" # Count bottom row.239 IsValid $t_bot $row240 if [ $? -eq "$TRUE" ]241 then242 if [ ${array[$t_bot]} = "$ALIVE1" ] 243 then244 let "count += 1"245 fi 246 fi 247 248 done 249 250 251 if [ ${array[$cell_number]} = "$ALIVE1" ]252 then253 let "count -= 1" # Make sure value of tested cell itself254 fi #+ is not counted.255 256 257 return $count258 259 }260 261 next_gen () # Update generation array.262 {263 264 local array265 local i=0266 267 array=( `echo "$1"` ) # Convert passed arg to array.268 269 while [ "$i" -lt "$cells" ]270 do271 IsAlive "$1" $i ${array[$i]} # Is cell alive?272 if [ $? -eq "$ALIVE" ]273 then # If alive, then274 array[$i]=. #+ represent the cell as a period.275 else 276 array[$i]="_" # Otherwise underscore277 fi #+ (which will later be converted to space). 278 let "i += 1" 279 done 280 281 282 # let "generation += 1" # Increment generation count.283 # Why was the above line commented out?284 285 286 # Set variable to pass as parameter to "display" function.287 avar=`echo ${array[@]}` # Convert array back to string variable.288 display "$avar" # Display it.289 echo; echo290 echo "Generation $generation - $alive alive"291 292 if [ "$alive" -eq 0 ]293 then294 echo295 echo "Premature exit: no more cells alive!"296 exit $NONE_ALIVE # No point in continuing297 fi #+ if no live cells.298 299 }300 301 302 # =========================================================303 304 # main ()305
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?