contributed-scripts.html

来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 2,144 行 · 第 1/5 页

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

⌨️ 快捷键说明

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