📄 contributed-scripts.html
字号:
21 E_WRONGARGS=70 22 23 if [ $# -ne "$ARGCOUNT" ] 24 then 25 echo "Usage: `basename $0` name" 26 exit $E_WRONGARGS 27 fi 28 29 30 assign_value () # Assigns numerical value 31 { #+ to letters of name. 32 33 val1=bfpv # 'b,f,p,v' = 1 34 val2=cgjkqsxz # 'c,g,j,k,q,s,x,z' = 2 35 val3=dt # etc. 36 val4=l 37 val5=mn 38 val6=r 39 40 # Exceptionally clever use of 'tr' follows. 41 # Try to figure out what is going on here. 42 43 value=$( echo "$1" \ 44 | tr -d wh \ 45 | tr $val1 1 | tr $val2 2 | tr $val3 3 \ 46 | tr $val4 4 | tr $val5 5 | tr $val6 6 \ 47 | tr -s 123456 \ 48 | tr -d aeiouy ) 49 50 # Assign letter values. 51 # Remove duplicate numbers, except when separated by vowels. 52 # Ignore vowels, except as separators, so delete them last. 53 # Ignore 'w' and 'h', even as separators, so delete them first. 54 # 55 # The above command substitution lays more pipe than a plumber <g>. 56 57 } 58 59 60 input_name="$1" 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 $char1 100 s3=$value 101 s3=9$s3 # If first letter of name is a vowel 102 #+ or 'w' or 'h', 103 #+ then its "value" will be null (unset). 104 #+ Therefore, set it to 9, an otherwise 105 #+ unused value, which can be tested for. 106 107 108 if [[ "$s1" -ne "$s2" || "$s3" -eq 9 ]] 109 then 110 suffix=$s2 111 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 echo 128 129 # The soundex code is a method of indexing and classifying names 130 #+ 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-625 138 # Hargison = H-622 139 # Harriman = H-655 140 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.html 150 151 152 153 # Exercise: 154 # -------- 155 # Simplify the "Exception Patch" section of this script. 156 157 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="LIFEREF"></A></P><DIVCLASS="EXAMPLE"><HR><ANAME="LIFESLOW"></A><P><B>Example A-10. <ICLASS="FIRSTTERM">Game of Life</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><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 rowcheck 100 101 for ((i=0; i<$element_count; i++)) 102 do 103 104 # Insert newline at end of each row. 105 let "rowcheck = $i % COLS" 106 if [ "$rowcheck" -eq 0 ] 107 then 108 echo # Newline. 109 echo -n " " # Indent. 110 fi 111 112 cell=${arr[i]} 113 114 if [ "$cell" = . ] 115 then 116 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 return 124 125 } 126 127 IsValid () # Test whether cell coordinate valid. 128 { 129 130 if [ -z "$1" -o -z "$2" ] # Mandatory arguments missing? 131 then 132 return $FALSE 133 fi 134 135 local row 136 local lower_limit=0 # Disallow negative coordinate. 137 local upper_limit 138 local left 139 local right 140 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 then 146 return $FALSE # Out of array bounds. 147 fi 148 149 row=$2 150 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 then 155 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 then 172 return $ALIVE 173 fi 174 175 if [ "$3" = "." -a "$nhbd" -eq "$SURVIVE" ] 176 then # Alive only if previously alive. 177 return $ALIVE 178 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 array 188 # $2) cell number 189 { 190 local cell_number=$2 191 local array 192 local top 193 local center 194 local bottom 195 local r 196 local row 197 local i 198 local t_top 199 local t_cen 200 local t_bot 201 local count=0 202 local ROW_NHBD=3 203 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 do 213 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 then 222 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 $row 230 if [ $? -eq "$TRUE" ] 231 then 232 if [ ${array[$t_top]} = "$ALIVE1" ] 233 then 234 let "count += 1" 235 fi 236 fi 237 238 let "row = $r + 1" # Count bottom row. 239 IsValid $t_bot $row 240 if [ $? -eq "$TRUE" ] 241 then 242 if [ ${array[$t_bot]} = "$ALIVE1" ] 243 then 244 let "count += 1" 245 fi 246 fi 247 248 done
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -