contributed-scripts.html

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

HTML
2,144
字号
 38&nbsp; 39&nbsp;case "$answer" in 40&nbsp;[yY]) rm -f $OF 41&nbsp;      echo "$OF erased." 42&nbsp;      ;; 43&nbsp;*)    echo "$OF not erased.";; 44&nbsp;esac 45&nbsp; 46&nbsp;echo 47&nbsp; 48&nbsp;# Exercise: 49&nbsp;# Change the above "case" statement to also accept "yes" and "Yes" as input. 50&nbsp; 51&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="COLLATZ"></A><P><B>例子 A-6. Collatz序列</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# collatz.sh  3&nbsp;  4&nbsp;#  The notorious "hailstone" or Collatz series.  5&nbsp;#  -------------------------------------------  6&nbsp;#  1) Get the integer "seed" from the command line.  7&nbsp;#  2) NUMBER &#60;--- seed  8&nbsp;#  3) Print NUMBER.  9&nbsp;#  4)  If NUMBER is even, divide by 2, or 10&nbsp;#  5)+ if odd, multiply by 3 and add 1. 11&nbsp;#  6) NUMBER &#60;--- result  12&nbsp;#  7) Loop back to step 3 (for specified number of iterations). 13&nbsp;# 14&nbsp;#  The theory is that every sequence, 15&nbsp;#+ no matter how large the initial value, 16&nbsp;#+ eventually settles down to repeating "4,2,1..." cycles, 17&nbsp;#+ even after fluctuating through a wide range of values. 18&nbsp;# 19&nbsp;#  This is an instance of an "iterate", 20&nbsp;#+ an operation that feeds its output back into the input. 21&nbsp;#  Sometimes the result is a "chaotic" series. 22&nbsp; 23&nbsp; 24&nbsp;MAX_ITERATIONS=200 25&nbsp;# For large seed numbers (&#62;32000), increase MAX_ITERATIONS. 26&nbsp; 27&nbsp;h=${1:-$$}                      #  Seed 28&nbsp;                                #  Use $PID as seed, 29&nbsp;                                #+ if not specified as command-line arg. 30&nbsp; 31&nbsp;echo 32&nbsp;echo "C($h) --- $MAX_ITERATIONS Iterations" 33&nbsp;echo 34&nbsp; 35&nbsp;for ((i=1; i&#60;=MAX_ITERATIONS; i++)) 36&nbsp;do 37&nbsp; 38&nbsp;echo -n "$h	" 39&nbsp;#          ^^^^^ 40&nbsp;#           tab 41&nbsp; 42&nbsp;  let "remainder = h % 2" 43&nbsp;  if [ "$remainder" -eq 0 ]   # Even? 44&nbsp;  then 45&nbsp;    let "h /= 2"              # Divide by 2. 46&nbsp;  else 47&nbsp;    let "h = h*3 + 1"         # Multiply by 3 and add 1. 48&nbsp;  fi 49&nbsp; 50&nbsp; 51&nbsp;COLUMNS=10                    # Output 10 values per line. 52&nbsp;let "line_break = i % $COLUMNS" 53&nbsp;if [ "$line_break" -eq 0 ] 54&nbsp;then 55&nbsp;  echo 56&nbsp;fi   57&nbsp; 58&nbsp;done 59&nbsp; 60&nbsp;echo 61&nbsp; 62&nbsp;#  For more information on this mathematical function, 63&nbsp;#+ see "Computers, Pattern, Chaos, and Beauty", by Pickover, p. 185 ff., 64&nbsp;#+ as listed in the bibliography. 65&nbsp; 66&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="DAYSBETWEEN"></A><P><B>例子 A-7. <BCLASS="COMMAND">days-between</B>: 计算两个日期之间天数差</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# days-between.sh:    Number of days between two dates.  3&nbsp;# Usage: ./days-between.sh [M]M/[D]D/YYYY [M]M/[D]D/YYYY  4&nbsp;#  5&nbsp;# Note: Script modified to account for changes in Bash 2.05b  6&nbsp;#+      that closed the loophole permitting large negative  7&nbsp;#+      integer return values.  8&nbsp;  9&nbsp;ARGS=2                # Two command line parameters expected. 10&nbsp;E_PARAM_ERR=65        # Param error. 11&nbsp; 12&nbsp;REFYR=1600            # Reference year. 13&nbsp;CENTURY=100 14&nbsp;DIY=365 15&nbsp;ADJ_DIY=367           # Adjusted for leap year + fraction. 16&nbsp;MIY=12 17&nbsp;DIM=31 18&nbsp;LEAPCYCLE=4 19&nbsp; 20&nbsp;MAXRETVAL=255         #  Largest permissable 21&nbsp;                      #+ positive return value from a function. 22&nbsp; 23&nbsp;diff=                 # Declare global variable for date difference. 24&nbsp;value=                # Declare global variable for absolute value. 25&nbsp;day=                  # Declare globals for day, month, year. 26&nbsp;month= 27&nbsp;year= 28&nbsp; 29&nbsp; 30&nbsp;Param_Error ()        # Command line parameters wrong. 31&nbsp;{ 32&nbsp;  echo "Usage: `basename $0` [M]M/[D]D/YYYY [M]M/[D]D/YYYY" 33&nbsp;  echo "       (date must be after 1/3/1600)" 34&nbsp;  exit $E_PARAM_ERR 35&nbsp;}   36&nbsp; 37&nbsp; 38&nbsp;Parse_Date ()                 # Parse date from command line params. 39&nbsp;{ 40&nbsp;  month=${1%%/**} 41&nbsp;  dm=${1%/**}                 # Day and month. 42&nbsp;  day=${dm#*/} 43&nbsp;  let "year = `basename $1`"  # Not a filename, but works just the same. 44&nbsp;}   45&nbsp; 46&nbsp; 47&nbsp;check_date ()                 # Checks for invalid date(s) passed. 48&nbsp;{ 49&nbsp;  [ "$day" -gt "$DIM" ] || [ "$month" -gt "$MIY" ] || [ "$year" -lt "$REFYR" ] &#38;&#38; Param_Error 50&nbsp;  # Exit script on bad value(s). 51&nbsp;  # Uses "or-list / and-list". 52&nbsp;  # 53&nbsp;  # Exercise: Implement more rigorous date checking. 54&nbsp;} 55&nbsp; 56&nbsp; 57&nbsp;strip_leading_zero () #  Better to strip possible leading zero(s) 58&nbsp;{                     #+ from day and/or month 59&nbsp;  return ${1#0}       #+ since otherwise Bash will interpret them 60&nbsp;}                     #+ as octal values (POSIX.2, sect 2.9.2.1). 61&nbsp; 62&nbsp; 63&nbsp;day_index ()          # Gauss' Formula: 64&nbsp;{                     # Days from Jan. 3, 1600 to date passed as param. 65&nbsp; 66&nbsp;  day=$1 67&nbsp;  month=$2 68&nbsp;  year=$3 69&nbsp; 70&nbsp;  let "month = $month - 2" 71&nbsp;  if [ "$month" -le 0 ] 72&nbsp;  then 73&nbsp;    let "month += 12" 74&nbsp;    let "year -= 1" 75&nbsp;  fi   76&nbsp; 77&nbsp;  let "year -= $REFYR" 78&nbsp;  let "indexyr = $year / $CENTURY" 79&nbsp; 80&nbsp; 81&nbsp;  let "Days = $DIY*$year + $year/$LEAPCYCLE - $indexyr + $indexyr/$LEAPCYCLE + $ADJ_DIY*$month/$MIY + $day - $DIM" 82&nbsp;  #  For an in-depth explanation of this algorithm, see 83&nbsp;  #+ http://home.t-online.de/home/berndt.schwerdtfeger/cal.htm 84&nbsp; 85&nbsp; 86&nbsp;  echo $Days 87&nbsp; 88&nbsp;}   89&nbsp; 90&nbsp; 91&nbsp;calculate_difference ()            # Difference between to day indices. 92&nbsp;{ 93&nbsp;  let "diff = $1 - $2"             # Global variable. 94&nbsp;}   95&nbsp; 96&nbsp; 97&nbsp;abs ()                             #  Absolute value 98&nbsp;{                                  #  Uses global "value" variable. 99&nbsp;  if [ "$1" -lt 0 ]                #  If negative100&nbsp;  then                             #+ then101&nbsp;    let "value = 0 - $1"           #+ change sign,102&nbsp;  else                             #+ else103&nbsp;    let "value = $1"               #+ leave it alone.104&nbsp;  fi105&nbsp;}106&nbsp;107&nbsp;108&nbsp;109&nbsp;if [ $# -ne "$ARGS" ]              # Require two command line params.110&nbsp;then111&nbsp;  Param_Error112&nbsp;fi  113&nbsp;114&nbsp;Parse_Date $1115&nbsp;check_date $day $month $year       #  See if valid date.116&nbsp;117&nbsp;strip_leading_zero $day            #  Remove any leading zeroes118&nbsp;day=$?                             #+ on day and/or month.119&nbsp;strip_leading_zero $month120&nbsp;month=$?121&nbsp;122&nbsp;let "date1 = `day_index $day $month $year`"123&nbsp;124&nbsp;125&nbsp;Parse_Date $2126&nbsp;check_date $day $month $year127&nbsp;128&nbsp;strip_leading_zero $day129&nbsp;day=$?130&nbsp;strip_leading_zero $month131&nbsp;month=$?132&nbsp;133&nbsp;date2=$(day_index $day $month $year) # Command substitution.134&nbsp;135&nbsp;136&nbsp;calculate_difference $date1 $date2137&nbsp;138&nbsp;abs $diff                            # Make sure it's positive.139&nbsp;diff=$value140&nbsp;141&nbsp;echo $diff142&nbsp;143&nbsp;exit 0144&nbsp;#  Compare this script with145&nbsp;#+ the implementation of Gauss' Formula in a C program at:146&nbsp;#+    http://buschencrew.hypermart.net/software/datedif</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="MAKEDICT"></A><P><B>例子 A-8. 构造一个<SPANCLASS="QUOTE">"字典"</SPAN></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# makedict.sh  [make dictionary]  3&nbsp;  4&nbsp;# Modification of /usr/sbin/mkdict script.  5&nbsp;# Original script copyright 1993, by Alec Muffett.  6&nbsp;#  7&nbsp;#  This modified script included in this document in a manner  8&nbsp;#+ consistent with the "LICENSE" document of the "Crack" package  9&nbsp;#+ that the original script is a part of. 10&nbsp; 11&nbsp;#  This script processes text files to produce a sorted list 12&nbsp;#+ of words found in the files. 13&nbsp;#  This may be useful for compiling dictionaries 14&nbsp;#+ and for lexicographic research. 15&nbsp; 16&nbsp; 17&nbsp;E_BADARGS=65 18&nbsp; 19&nbsp;if [ ! -r "$1" ]                     #  Need at least one 20&nbsp;then                                 #+ valid file argument. 21&nbsp;  echo "Usage: $0 files-to-process" 22&nbsp;  exit $E_BADARGS 23&nbsp;fi   24&nbsp; 25&nbsp; 26&nbsp;# SORT="sort"                        #  No longer necessary to define options 27&nbsp;                                     #+ to sort. Changed from original script. 28&nbsp; 29&nbsp;cat $* |                             # Contents of specified files to stdout. 30&nbsp;        tr A-Z a-z |                 # Convert to lowercase. 31&nbsp;        tr ' ' '\012' |              # New: change spaces to newlines. 32&nbsp;#       tr -cd '\012[a-z][0-9]' |    #  Get rid of everything non-alphanumeric 33&nbsp;                                     #+ (original script). 34&nbsp;        tr -c '\012a-z'  '\012' |    #  Rather than deleting 35&nbsp;                                     #+ now change non-alpha to newlines. 36&nbsp;        sort |                       # $SORT options unnecessary now. 37&nbsp;        uniq |                       # Remove duplicates. 38&nbsp;        grep -v '^#' |               # Delete lines beginning with a hashmark. 39&nbsp;        grep -v '^$'                 # Delete blank lines. 40&nbsp; 41&nbsp;exit 0	</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="SOUNDEX"></A><P><B>例子 A-9. Soundex转换</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# soundex.sh: Calculate "soundex" code for names  3&nbsp;  4&nbsp;# =======================================================  5&nbsp;#        Soundex script  6&nbsp;#              by  7&nbsp;#         Mendel Cooper  8&nbsp;#     thegrendel@theriver.com  9&nbsp;#       23 January, 2002 10&nbsp;# 11&nbsp;#   Placed in the Public Domain. 12&nbsp;# 13&nbsp;# A slightly different version of this script appeared in 14&nbsp;#+ Ed Schaefer's July, 2002 "Shell Corner" column 15&nbsp;#+ in "Unix Review" on-line, 16&nbsp;#+ http://www.unixreview.com/documents/uni1026336632258/ 17&nbsp;# ======================================================= 18&nbsp; 19&nbsp; 20&nbsp;ARGCOUNT=1                     # Need name as argument. 21&nbsp;E_WRONGARGS=70 22&nbsp; 23&nbsp;if [ $# -ne "$ARGCOUNT" ] 24&nbsp;then 25&nbsp;  echo "Usage: `basename $0` name" 26&nbsp;  exit $E_WRONGARGS 27&nbsp;fi   28&nbsp; 29&nbsp; 30&nbsp;assign_value ()                #  Assigns numerical value 31&nbsp;{                              #+ to letters of name. 32&nbsp; 33&nbsp;  val1=bfpv                    # 'b,f,p,v' = 1 34&nbsp;  val2=cgjkqsxz                # 'c,g,j,k,q,s,x,z' = 2 35&nbsp;  val3=dt                      #  etc. 36&nbsp;  val4=l 37&nbsp;  val5=mn 38&nbsp;  val6=r 39&nbsp; 40&nbsp;# Exceptionally clever use of 'tr' follows. 41&nbsp;# Try to figure out what is going on here. 42&nbsp; 43&nbsp;value=$( echo "$1" \ 44&nbsp;| tr -d wh \ 45&nbsp;| tr $val1 1 | tr $val2 2 | tr $val3 3 \ 46&nbsp;| tr $val4 4 | tr $val5 5 | tr $val6 6 \ 47&nbsp;| tr -s 123456 \ 48&nbsp;| tr -d aeiouy ) 49&nbsp; 50&nbsp;# Assign letter values. 51&nbsp;# Remove duplicate numbers, except when separated by vowels. 52&nbsp;# Ignore vowels, except as separators, so delete them last. 53&nbsp;# Ignore 'w' and 'h', even as separators, so delete them first. 54&nbsp;# 55&nbsp;# The above command substitution lays more pipe than a plumber &#60;g&#62;. 56&nbsp; 57&nbsp;}   58&nbsp; 59&nbsp; 60&nbsp;input_name="$1"

⌨️ 快捷键说明

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