99 Bottles of Beer/Shell: Difference between revisions

From Rosetta Code
Content added Content deleted
m (moving code from main task-page to sub-page)
m (Fixed syntax highlighting and duplicate headers.)
 
(11 intermediate revisions by 6 users not shown)
Line 1: Line 1:
=Task in Shell(s)=
<!-- =Task in Shell(s)= -->
{{collection|99 Bottles of Beer}} [[implementation of task::99 Bottles of Beer| ]]
{{collection|99 Bottles of Beer}}
[[implementation of task::99 Bottles of Beer| ]]

[[99 Bottles of Beer]] done in any of the Shell-languages.
[[99 Bottles of Beer]] done in any of the Shell-languages.
<br><br>
__toc__

===AutoHotkey===
<syntaxhighlight lang="autoHotkey">; RC: 99 bottles of beer
b = 99
Loop, %b% {
s .= b . " bottles of beer on the wall,`n"
. b . " bottles of beer.`nTake one down, pass it around,`n"
. b-1 . " bottles of beer on the wall.`n`n"
b--
}
Gui, Add, Edit, w200 h200, %s%
Gui, Show, , 99 bottles of beer
Return ; end of auto-execute section

GuiClose:
ExitApp
Return</syntaxhighlight>

Delayed Sing along
<syntaxhighlight lang="autoHotkey">n=99
Gui, Font, s20 cMaroon, Comic Sans MS
Gui, Add, Text, w500 vLyrics, %n% bottles of beer on the wall...
Gui, Show
Loop {
Sleep, 2000
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer.":n " bottle of beer."
Sleep, 2000
GuiControl,,Lyrics,% n ? "Take one down, pass it around...":"Go to the store, buy some more..."
Sleep, 2000
n := n ? --n:99
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer on the wall.":n " bottle of beer on the wall."
Sleep, 2000
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer on the wall...":n " bottle of beer on the wall..."
}
GuiClose:
ExitApp</syntaxhighlight>

Fast and Short:
<syntaxhighlight lang="autoHotkey">b=99
Loop, %b% {
s := b " bottles of beer on the wall, " b " bottles of beer, Take one down, pass it around " b-1 " bottles of beer on the wall"
b--
TrayTip,,%s%
sleep, 40
}</syntaxhighlight>

With a GUI and slight grammatical variation:
<syntaxhighlight lang="autoHotkey">N=o more
Z=99
L:=Z M:=(B:=" bottle")"s"
Loop 99
V.=L (W:=(O:=" of beer")" on the wall")",`n"L O ",`nTake one down and pass it around,`n"(L:=(--Z ? Z:"N"N)(Z=1 ? B:M))W ".`n`n"
Gui,Add,Edit,w600 h250,% V L W ", n"N M O ".`nGo to the store and buy some more, 99"M W "."
Gui,Show
Return
GuiClose:
ExitApp</syntaxhighlight>

Recursive with slight grammatical variation:
<syntaxhighlight lang="autoHotkey">99bottles()
esc::exitapp
99bottles(x=99) {
ToolTip, % Format("{1:} {2:} of beer on the wall, {1:L} {2:} of beer.{4:}{3:} {2:} of beer on the wall!"
,(x?x:"No more")
,(x=1?"bottle":"bottles")
,(x=1?"no more":x=0?99:x-1)
,(x?"`nYou take one down pass it around, ":"`nGo to the store and buy some more, ")),500,300
sleep 99
x?99bottles(x-1):return
}</syntaxhighlight>

===AutoIt===
<syntaxhighlight lang="autoit">local $bottleNo=99
local $lyrics=" "

While $bottleNo<>0
If $bottleNo=1 Then
$lyrics&=$bottleNo & " bottles of beer on the wall" & @CRLF
$lyrics&=$bottleNo & " bottles of beer" & @CRLF
$lyrics&="Take one down, pass it around" & @CRLF
Else
$lyrics&=$bottleNo & " bottles of beer on the wall" & @CRLF
$lyrics&=$bottleNo & " bottles of beer" & @CRLF
$lyrics&="Take one down, pass it around" & @CRLF
EndIf
If $bottleNo=1 Then
$lyrics&=$bottleNo-1 & " bottle of beer" & @CRLF
Else
$lyrics&=$bottleNo-1 & " bottles of beer" & @CRLF
EndIf
$bottleNo-=1
WEnd
MsgBox(1,"99",$lyrics)</syntaxhighlight>

Easier to read output to Console:
<syntaxhighlight lang="autoit">
$bottles = 99
$lyrics1 = " bottles of beer on the wall. "
$lyrics2 = " bottles of beer. Take one down and pass it around. "

For $i = $bottles To 1 Step -1
If $i = 1 Then
$lyrics1 = " bottle of beer on the wall. "
$lyrics2 = " bottle of beer. Take one down and pass it around. "
$lyrics3 = " Go to the store and get some more! No bottles of beer on the wall!"
ConsoleWrite($bottles & $lyrics1 & $bottles & $lyrics2 & $lyrics3 & @CRLF)
Else
ConsoleWrite($bottles & $lyrics1 & $bottles & $lyrics2 & $bottles - 1 & $lyrics1 & @CRLF)
$bottles -= 1
EndIf
Next</syntaxhighlight>


=={{header|Batch File}}==
===Batch File===


<lang dos>@echo off
<syntaxhighlight lang="dos">@echo off
setlocal
setlocal
:main
:main
Line 52: Line 166:
set %2=one
set %2=one
)
)
goto :eof</lang>
goto :eof</syntaxhighlight>


=={{header|friendly interactive shell}}==
===friendly interactive shell===
<lang fishshell>set i 99
<syntaxhighlight lang="fishshell">set i 99
# Assign s to variable $s
# Assign s to variable $s
set s s
set s s
Line 72: Line 186:
echo
echo
end
end
end</lang>
end</syntaxhighlight>


===PowerShell===
====A standard impementation using a For loop====
<syntaxhighlight lang="powershell">for($n=99; $n -gt 0; $n--) {
"$n bottles of beer on the wall"
"$n bottles of beer"
"Take one down, pass it around"
[string]($n-1) + " bottles of beer on the wall"
""
}</syntaxhighlight>



=={{header|UNIX Shell}}==
====My standard implementation using for loop====
<syntaxhighlight lang="powershell">[int]$i = 99;
for($i=99; $i -gt 0; $i--) {
write-host $i " bottles of beer on the wall";
write-host $i " bottles of beer";
write-host "Take one down, pass it around"
write-host ($i-1) " bottles of beer on the wall"
write-host ""
}</syntaxhighlight>

====Consolidating the static text and using a Do...while loop====
<syntaxhighlight lang="powershell">$n=99
do {
"{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n" -f $n, --$n
} while ($n -gt 0)</syntaxhighlight>

====Consolidating the static text and using a Do...until loop====
<syntaxhighlight lang="powershell">$n=99
do {
"{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n" -f $n, --$n
} until ($n -eq 0)</syntaxhighlight>


====Consolidating the static text even more====
<syntaxhighlight lang="powershell">$s = "{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n"
$n=99
do { $s -f $n, --$n } while ($n -gt 0)</syntaxhighlight>

====Using the Pipeline====
<syntaxhighlight lang="powershell">99..1 | ForEach-Object {
$s=$( if( $_ -ne 1 ) { 's' } else { '' } )
$s2=$( if( $_ -ne 2 ) { 's' } else { '' } )
"$_ bottle$s of beer on the wall`n$_ bottle$s of beer`nTake one down`npass it around`n$( $_ - 1 ) bottle$s2 of beer on the wall`n"}</syntaxhighlight>

===ProDOS===
<syntaxhighlight lang="prodos">editvar /newvar /value=a=99
:a
printline -a- bottles of beer on the wall
printline -a- bottles of beer
printline Take one down, pass it round
editvar /newvar /value=a=-a-1
if -a- /hasvalue 1 goto :1
printline -a- bottles of beer on the wall.
goto :a
:1
printline 1 bottle of beer on the wall
printline 1 bottle of beer
printline take it down, pass it round
printline no bottles of beer on the wall.
editvar /newvar /value=b /userinput=1 /title=Keep drinking?
if -b- /hasvalue yes goto :a else exitprogram</syntaxhighlight>

===UNIX Shell===
{{works with|Bourne Shell}}
{{works with|Bourne Shell}}
<lang bash>#!/bin/sh
<syntaxhighlight lang="bash">#!/bin/sh


i=99 s=s
i=99 s=s
Line 87: Line 263:
# POSIX allows for $(( i - 1 )) but some older Unices didn't have that
# POSIX allows for $(( i - 1 )) but some older Unices didn't have that
i=`expr $i - 1`
i=`expr $i - 1`
[ $i -eq 1 ] && s= || s=s
[ $i -eq 1 ] && s=
echo "$i bottle$s of beer on the wall
echo "$i bottle$s of beer on the wall
"
"
done</lang>
done</syntaxhighlight>


{{works with|Bash}}
{{works with|Bash}}
{{works with|ksh93}}
{{works with|ksh93}}
{{works with|zsh}}
{{works with|zsh}}
<lang bash>bottles() {
<syntaxhighlight lang="bash">bottles() {
beer=$1
beer=$1
[ $((beer)) -gt 0 ] && echo -n $beer || echo -n "No more"
(( beer > 0 )) && printf '%d' $beer || printf "No more"
echo -n " bottle"
printf " bottle"
[ $((beer)) -ne 1 ] && echo -n "s"
((beer != 1 )) && printf "s"
echo -n " of beer"
printf " of beer"
}
}


for ((i=99;i>=0;i--)); do
for ((i=99;i>=0;i--)); do
((remaining=i))
((remaining=i))
echo "$(bottles $remaining) on the wall"
printf '%s on the wall\n' "$(bottles $remaining)"
echo "$(bottles $remaining)"
printf '%s\n' "$(bottles $remaining)"
if [ $((remaining)) -eq 0 ]; then
if (( remaining == 0 )); then
echo "Go to the store and buy some more"
printf 'Go to the store and buy some more\n'
((remaining+=99))
((remaining+=99))
else
else
echo "Take one down, pass it around"
printf 'Take one down, pass it around\n'
((remaining--))
((remaining--))
fi
fi
echo "$(bottles $remaining) on the wall"
printf '%s on the wall\n\n' "$(bottles $remaining)"
done</syntaxhighlight>
echo
done</lang>


==={{header|C Shell}}===
====C Shell====
<syntaxhighlight lang="csh">@ i=99
See [[99 Bottles of Beer/Shell]]
<lang csh>@ i=99
set s=s
set s=s
while ($i > 0)
while ($i > 0)
Line 134: Line 308:
echo "$i bottle$s of beer on the wall"
echo "$i bottle$s of beer on the wall"
echo ""
echo ""
end</lang>
end</syntaxhighlight>

====es====
es - extensible shell

<syntaxhighlight lang="es">i = 99
s = s
while {test $i -gt 0} {
echo $i bottle$s of beer on the wall
echo $i bottle$s of beer
echo Take one down, pass it around
i = `{expr $i - 1}
if {test $i -eq 1} {s = ''} {s = s}
echo $i bottle$s of beer on the wall
echo
}</syntaxhighlight>

===UnixPipes===
<syntaxhighlight lang="bash"># Unix Pipes, avoiding all the turing complete sub programs like sed, awk, dc etc.
mkdir 99 || exit 1
trap "rm -rf 99" 1 2 3 4 5 6 7 8

(cd 99
mkfifo p.b1 p.b2 p.verse1 p.wall p.take
yes "on the wall" > p.wall &
yes "Take one down and pass it around, " > p.take &
(yes "bottles of beer" | nl -s\ | head -n 99 | tac | head -n 98 ;
echo "One bottle of beer";
echo "No more bottles of beer") | tee p.b1 p.b2 |
paste -d"\ " - p.wall p.b1 p.take | head -n 99 > p.verse1 &
cat p.b2 | tail -99 | paste -d"\ " p.verse1 - p.wall | head -n 99
)
rm -rf 99</syntaxhighlight>

Latest revision as of 20:03, 1 September 2022

99 Bottles of Beer/Shell is part of 99 Bottles of Beer. You may find other members of 99 Bottles of Beer at Category:99 Bottles of Beer.


99 Bottles of Beer done in any of the Shell-languages.

AutoHotkey

; RC: 99 bottles of beer
   b = 99
   Loop, %b% {
      s .= b . " bottles of beer on the wall,`n"
        . b . " bottles of beer.`nTake one down, pass it around,`n"
        . b-1 . " bottles of beer on the wall.`n`n"
      b--
   }
   Gui, Add, Edit, w200 h200, %s%
   Gui, Show, , 99 bottles of beer
Return ; end of auto-execute section

GuiClose:
   ExitApp
Return

Delayed Sing along

n=99
Gui, Font, s20 cMaroon, Comic Sans MS
Gui, Add, Text, w500 vLyrics, %n% bottles of beer on the wall...
Gui, Show
Loop {
 Sleep, 2000
 GuiControl,,Lyrics,% n!=1 ? n " bottles of beer.":n " bottle of beer."
 Sleep, 2000
 GuiControl,,Lyrics,% n ? "Take one down, pass it around...":"Go to the store, buy some more..."
 Sleep, 2000
 n := n ? --n:99
 GuiControl,,Lyrics,% n!=1 ? n " bottles of beer on the wall.":n " bottle of beer on the wall."
 Sleep, 2000
 GuiControl,,Lyrics,% n!=1 ? n " bottles of beer on the wall...":n " bottle of beer on the wall..."
}
GuiClose:
ExitApp

Fast and Short:

b=99
Loop, %b% {
s := b " bottles of beer on the wall, " b " bottles of beer, Take one down, pass it around " b-1 " bottles of beer on the wall"
b--
TrayTip,,%s%
sleep, 40
}

With a GUI and slight grammatical variation:

N=o more
Z=99
L:=Z M:=(B:=" bottle")"s"
Loop 99
V.=L (W:=(O:=" of beer")" on the wall")",`n"L O ",`nTake one down and pass it around,`n"(L:=(--Z ? Z:"N"N)(Z=1 ? B:M))W ".`n`n"
Gui,Add,Edit,w600 h250,% V L W ", n"N M O ".`nGo to the store and buy some more, 99"M W "."
Gui,Show
Return
GuiClose:
ExitApp

Recursive with slight grammatical variation:

99bottles()
esc::exitapp
 
99bottles(x=99) { 
  ToolTip, % Format("{1:} {2:} of beer on the wall, {1:L} {2:} of beer.{4:}{3:} {2:} of beer on the wall!"
  ,(x?x:"No more")
  ,(x=1?"bottle":"bottles")
  ,(x=1?"no more":x=0?99:x-1)
  ,(x?"`nYou take one down pass it around, ":"`nGo to the store and buy some more, ")),500,300
  sleep 99
  x?99bottles(x-1):return       
}

AutoIt

local $bottleNo=99
local $lyrics=" "

While $bottleNo<>0
	If $bottleNo=1 Then
		$lyrics&=$bottleNo & " bottles of beer on the wall" & @CRLF
		$lyrics&=$bottleNo & " bottles of beer" & @CRLF
		$lyrics&="Take one down, pass it around" & @CRLF
	Else
		$lyrics&=$bottleNo & " bottles of beer on the wall" & @CRLF
		$lyrics&=$bottleNo & " bottles of beer" & @CRLF
		$lyrics&="Take one down, pass it around" & @CRLF
	EndIf
	If $bottleNo=1 Then
		$lyrics&=$bottleNo-1 & " bottle of beer" & @CRLF
	Else
		$lyrics&=$bottleNo-1 & " bottles of beer" & @CRLF
	EndIf
	$bottleNo-=1
WEnd
MsgBox(1,"99",$lyrics)

Easier to read output to Console:

$bottles = 99
$lyrics1 = " bottles of beer on the wall. "
$lyrics2 = " bottles of beer. Take one down and pass it around. "

	For $i = $bottles To 1 Step -1
		If $i = 1 Then
			$lyrics1 = " bottle of beer on the wall. "
			$lyrics2 = " bottle of beer. Take one down and pass it around. "
			$lyrics3 = " Go to the store and get some more! No bottles of beer on the wall!"
			ConsoleWrite($bottles & $lyrics1 & $bottles & $lyrics2 & $lyrics3 & @CRLF)
		Else
			ConsoleWrite($bottles & $lyrics1 & $bottles & $lyrics2 & $bottles - 1 & $lyrics1 & @CRLF)
			$bottles -= 1
		EndIf
	Next

Batch File

@echo off
setlocal 
:main
for /L %%i in (99,-1,1) do (
	call :verse %%i
)
echo no bottles of beer on the wall
echo no bottles of beer
echo go to the store and buy some more
echo 99 bottles of beer on the wall
echo.
set /p q="Keep drinking? "
if %q% == y goto main
if %q% == Y goto main
goto :eof

:verse
call :plural %1 res
echo %res% of beer on the wall 
echo %res% of beer
call :oneit %1 res
echo take %res% down and pass it round
set /a c=%1-1
call :plural %c% res
echo %res% of beer on the wall
echo.
goto :eof

:plural
if %1 gtr 1 goto :gtr
if %1 equ 1 goto :equ
set %2=no bottles
goto :eof
:gtr
set %2=%1 bottles
goto :eof
:equ
set %2=1 bottle
goto :eof

:oneit
if %1 equ 1 (
	set %2=it
) else (
	set %2=one
)
goto :eof

friendly interactive shell

set i 99
# Assign s to variable $s
set s s
while test $i != 'No more'
    echo $i bottle$s of beer on the wall,
    echo $i bottle$s of beer.
    echo Take one down, pass it around,
    set i (math $i - 1)
    if test $i -eq 1
        set s ""
    else if test $i -eq 0
        set i 'No more'
    end
    echo $i bottle$s of beer on the wall.
    if test $i != 'No more'
        echo
    end
end

PowerShell

A standard impementation using a For loop

for($n=99; $n -gt 0; $n--) {
   "$n bottles of beer on the wall"
   "$n bottles of beer"
   "Take one down, pass it around"
   [string]($n-1) + " bottles of beer on the wall"
   ""
}


My standard implementation using for loop

[int]$i = 99;
for($i=99; $i -gt 0; $i--) {
    write-host $i  " bottles of beer on the wall";
    write-host $i  " bottles of beer";
    write-host "Take one down, pass it around"
    write-host ($i-1) " bottles of beer on the wall"
    write-host ""
}

Consolidating the static text and using a Do...while loop

$n=99
do {
   "{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n" -f $n, --$n
} while ($n -gt 0)

Consolidating the static text and using a Do...until loop

$n=99
do {
   "{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n" -f $n, --$n
} until ($n -eq 0)


Consolidating the static text even more

$s = "{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n"
$n=99
do { $s -f $n, --$n } while ($n -gt 0)

Using the Pipeline

99..1 | ForEach-Object { 
    $s=$( if( $_ -ne 1 ) { 's' } else { '' } )
    $s2=$( if( $_ -ne 2 ) { 's' } else { '' } )
    "$_ bottle$s of beer on the wall`n$_ bottle$s of beer`nTake one down`npass it around`n$( $_ - 1 ) bottle$s2 of beer on the wall`n"}

ProDOS

editvar /newvar /value=a=99
:a
printline -a- bottles of beer on the wall
printline -a- bottles of beer
printline Take one down, pass it round
editvar /newvar /value=a=-a-1
if -a- /hasvalue 1 goto :1
printline -a- bottles of beer on the wall.
goto :a
:1 
printline 1 bottle of beer on the wall
printline 1 bottle of beer
printline take it down, pass it round
printline no bottles of beer on the wall.
editvar /newvar /value=b /userinput=1 /title=Keep drinking?
if -b- /hasvalue yes goto :a else exitprogram

UNIX Shell

Works with: Bourne Shell
#!/bin/sh

i=99 s=s

while [ $i -gt 0 ]; do
        echo "$i bottle$s of beer on the wall"
        echo "$i bottle$s of beer
Take one down, pass it around"
        # POSIX allows for $(( i - 1 )) but some older Unices didn't have that
        i=`expr $i - 1`
	[ $i -eq 1 ] && s=
        echo "$i bottle$s of beer on the wall
"
done
Works with: Bash
Works with: ksh93
Works with: zsh
bottles() {
  beer=$1
  (( beer > 0 )) && printf '%d' $beer ||  printf "No more"
  printf " bottle"
  ((beer != 1 )) && printf "s"
  printf " of beer"
}

for ((i=99;i>=0;i--)); do
  ((remaining=i))
  printf '%s on the wall\n' "$(bottles $remaining)"
  printf '%s\n' "$(bottles $remaining)"
  if (( remaining == 0 )); then
    printf 'Go to the store and buy some more\n'
    ((remaining+=99))
  else
    printf 'Take one down, pass it around\n'
    ((remaining--))
  fi
  printf '%s on the wall\n\n'  "$(bottles $remaining)"
done

C Shell

@ i=99
set s=s
while ($i > 0)
	echo "$i bottle$s of beer on the wall"
	echo "$i bottle$s of beer"
	echo "Take one down, pass it around"
	@ i = $i - 1
	if ($i == 1) then
		set s=
	else
		set s=s
	endif
	echo "$i bottle$s of beer on the wall"
	echo ""
end

es

es - extensible shell

i = 99
s = s
while {test $i -gt 0} {
	echo $i bottle$s of beer on the wall
	echo $i bottle$s of beer
	echo Take one down, pass it around
	i = `{expr $i - 1}
	if {test $i -eq 1} {s = ''} {s = s}
	echo $i bottle$s of beer on the wall
	echo
}

UnixPipes

# Unix Pipes, avoiding all the turing complete sub programs like sed, awk, dc etc.
mkdir 99 || exit 1
trap "rm -rf 99" 1 2 3 4 5 6 7 8

(cd 99
   mkfifo p.b1 p.b2 p.verse1 p.wall p.take
   yes "on the wall" > p.wall &
   yes "Take one down and pass it around, " > p.take &
   (yes "bottles of beer" | nl -s\ | head -n 99 | tac | head -n 98 ;
    echo "One bottle of beer";
    echo "No more bottles of beer") | tee p.b1 p.b2 |
   paste -d"\ " - p.wall p.b1 p.take | head -n 99 > p.verse1 &
   cat p.b2 | tail -99 | paste -d"\ " p.verse1 - p.wall | head -n 99
)
rm -rf 99