Browse Source

Add 99bottles.sh from http://99-bottles-of-beer.net/

    http://99-bottles-of-beer.net/language-bash-1831.html
Alois Mahdal 3 years ago
parent
commit
c9a24b2641
1 changed files with 161 additions and 0 deletions
  1. 161
    0
      99bottles.sh

+ 161
- 0
99bottles.sh View File

@@ -0,0 +1,161 @@
1
+#!/bin/bash
2
+#A way-overcomplicated implementation of the bottles
3
+# of beer song in bash.
4
+#Optional argument: --careless   Generate the "happen to fall" version
5
+
6
+standardBreakLine="Take one down and pass it around"
7
+wastefulBreakLine="If one of those bottles should happen to fall"
8
+breakLine=$([ "$1" = --careless ] && echo $wastefulBreakLine ||
9
+                                     echo $standardBreakLine)
10
+
11
+function pred() {  #get predecessor to a number
12
+  case $1 in
13
+    *nine)  echo ${1%nine}eight;;
14
+    *eight) echo ${1%eight}seven;;
15
+    *seven) echo ${1%seven}six;;
16
+    *six)   echo ${1%six}five;;
17
+    *five)  echo ${1%five}four;;
18
+    *four)  echo ${1%four}three;;
19
+    *three) echo ${1%three}two;;
20
+    *two)   echo ${1%two}one;;
21
+    one)    echo zero;;
22
+    *-one)  echo ${1%-one};;
23
+    *one)   echo ${1%one};;
24
+    ten)    echo nine;;
25
+    eleven) echo ten;;
26
+    twelve) echo eleven;;
27
+    *teen)  teenpred $1;;
28
+    *ty)    tenspred $1;;
29
+    zero)   echo "";  #to terminate
30
+  esac
31
+  }
32
+  
33
+function teenpred() { #predecessor of a teen
34
+  case $1 in
35
+     thirteen)   echo twelve;;
36
+     *)     echo $(crunchprefix $(pred $(uncrunchprefix ${1%teen})))teen;;
37
+     esac  
38
+  }
39
+  
40
+function tenspred() { #predecessor of a multiple of ten
41
+  case $1 in
42
+     twenty)     echo nineteen;;
43
+     *) echo $(crunchprefix --tens $(pred $(uncrunchprefix ${1%ty})))ty-nine;;
44
+     esac  
45
+  }
46
+  
47
+function crunchprefix() {
48
+  #crunch number prefix to its conventional form
49
+  # such as three --> thir
50
+  # option --tens     multiples of ten are a bit different
51
+  [ $1 = --tens ] && { tensop=true; shift; }
52
+  case $1 in 
53
+    two)   [ -n "$tensop" ] && echo twen || echo $1;;
54
+    three) echo thir;;
55
+    four)  [ -n "$tensop" ] && echo 'for' || echo $1;;
56
+    five)  echo fif;;
57
+    eight) [ -n "$tensop" ] && echo eigh || echo $1;;
58
+    *)     echo $1;;
59
+  esac
60
+  }
61
+
62
+function uncrunchprefix() { #reverse crunchprefix
63
+  case $1 in
64
+    twen)  echo two;;
65
+    thir)  echo three;;
66
+    'for') echo four;;
67
+    fif)   echo five;;
68
+    eigh)  echo eight;;
69
+    *)     echo $1;;
70
+  esac
71
+  }
72
+    
73
+function grammar() { #peculiarities of English grammar
74
+  local oneBottle=false  #can effect the following line
75
+  while read line; do
76
+    line="${line/one more bottles/one more bottle}"
77
+    case "$line" in
78
+       *"one of those bottles"*) line="$([ $oneBottle = true ] && 
79
+                         echo ${line/one of those bottles/that lone bottle} ||
80
+                         echo $line )"
81
+                         ;;
82
+       *"one down"*) line="$([ $oneBottle = true ] && 
83
+                         echo ${line/one down/it down} ||
84
+                         echo $line )"
85
+                         ;;
86
+       *bottles*)   oneBottle=false;;
87
+       *bottle*)    oneBottle=true;;
88
+       esac
89
+      #Some say the twenties should have no hyphen
90
+    line="${line/twenty-/twenty }"
91
+    echo $line
92
+    done
93
+  }
94
+  
95
+function capitalize() {  #fix beginning of each line
96
+  while read line; do
97
+    echo -n ${line:0:1} | tr '[:lower:]' '[:upper:]'
98
+    echo ${line#?}
99
+    done
100
+  }
101
+function punctuate() {  #add punct to each line
102
+  while read line; do 
103
+    case "${line}" in
104
+      [Ii]f*)   echo ${line},;;
105
+      '')       echo;;
106
+      *)        echo ${line}.;;
107
+      esac
108
+    done
109
+  }
110
+
111
+function verse () { #write one verse
112
+  local nb=$1
113
+  echo $nb bottles of beer on the wall
114
+  echo $nb bottles of beer
115
+  if [ $nb = zero ]; then
116
+    echo Go to the store and buy some more
117
+    nb=ninety-nine
118
+  else
119
+    echo $breakLine
120
+    nb=$(pred $nb)
121
+  fi
122
+  echo $nb bottles of beer on the wall
123
+  }
124
+  
125
+function poeticize() { #make it nice
126
+  while read first rest; do
127
+    case "$rest" in
128
+      *beer*)
129
+        first=${first/zero/no}
130
+        local syl=$(syllables ${first% *})
131
+        case $syl in  #improve meter
132
+          1|2)   echo $first 'more' $rest;;
133
+          *)     echo $first $rest;;
134
+          esac;;
135
+      *)         echo $first $rest
136
+      esac
137
+    done
138
+  }
139
+  
140
+function syllables { #estimate number of syls in word
141
+  local n=1
142
+  case $1 in
143
+    eleven)       n=2;; #sounds better if not considered 3
144
+    *teen)        n=2;;
145
+    *ty)          n=2;;
146
+    *-*)          n=3;; #don't care about more than 3
147
+    esac
148
+  case $1 in
149
+    *seven*)      let $((n = n+1));;
150
+    esac
151
+  echo $n
152
+  }
153
+    
154
+
155
+nb=ninety-nine
156
+
157
+while [ -n "$nb" ]; do
158
+  verse $nb
159
+  echo
160
+  nb=$(pred $nb)
161
+  done | poeticize | grammar | punctuate | capitalize