|
@@ -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
|