I want to get a string from user, for example adem. Then print this out like ascii text. Character should change, too (not only dots it may * - whatever user enters.)
.
. .
.......
. .
. .
Here is my bash script. I thought it could be useful if I divide them each row. Then concatenating each letters' own rows for each row.
echo Enter text:
read text
echo Enter character style:
read k
row1=([a]=" $k " [b]="$k$k$k$k$k" [c]="$k$k$k$k$k")
row2=([a]="$k $k" [b]="$k $k" [c]="$k ")
row3=([a]="$k $k" [b]="$k$k$k$k$k" [c]="$k ")
row4=([a]="$k$k$k$k$k" [b]="$k $k" [c]="$k ")
row5=([a]="$k $k" [b]="$k$k$k$k$k" [c]="$k$k$k$k$k")
strlen=${#text}
# Testing echo.
echo " $k $k $k "
echo $satir1[a]
for((i=0; i<=strlen; i ))
do
echostrline1 =${row1[${text:i:1}]}
echostrline2 =${row2[${text:i:1}]}
echostrline3 =${row3[${text:i:1}]}
echostrline4 =${row4[${text:i:1}]}
echostrline5 =${row5[${text:i:1}]}
done
echo $echostrline1
echo $echostrline2
echo $echostrline3
echo $echostrline4
echo $echostrline5
I have three problems, here.
- First I can not access row1[a] it doesn't work >> echo $satir1[a] (prints last element)
- When I run the script It's not printing the way I expected.
- If I enter * as a character it prints directory contents.
I tried to change for loop like that.
for((i=0; i<strlen; i ))
do
echostrline1 =" ${satir1[${metin:i:1}]}"
echostrline2 =" ${satir2[${metin:i:1}]}"
echostrline3 =" ${satir3[${metin:i:1}]}"
echostrline4 =" ${satir4[${metin:i:1}]}"
echostrline5 =" ${satir5[${metin:i:1}]}"
done
CodePudding user response:
If you paste your script into https://www.shellcheck.net/ and fix the errors there, all your questions should be solved. It is a great tool. Try it!
- First I can not access row1[a] it doesn't work >> echo $satir1[a] (prints last element)
Array access in bash does not work unless you add (the otherwise optional) parentheses around the expansion: $satir1[a]
--> ${satir1[a]}
.
- If I enter * as a character it prints directory contents.
Because the echo $echostrline1
at the end is unquoted, special symbols like *
and ?
are interpreted as glob patterns. Quoting prevents this.
- When I run the script It's not printing the way I expected
That's pretty vague. A question like this should make a concrete example. The main problem is probably with the missing quoting in echo $echostrline1
too. Because of word-splitting in unquoted variable expansions x="a b c"; echo $x
will be printed as a b c
(repeated spaces are squashed).
Also, like markp-fuso commented, the associative arrays have to be explicitly defined as such using declare -A row1=(...)
Btw: ((i=0; i<=strlen; i ))
iterates one time too much. E.g. text=abc
has three letters, but the loop tries to acces the 0
th, 1
th, 2
nd, and 3
rd letter (which does not exist).
Having one array for each letter seems a bit complicated and also makes it harder to change the letter size. Hence, I'd propose below solution:
#! /bin/bash
IFS= read -p"Enter text: " -r text
IFS= read -p"Enter character style: " -n1 -r k
echo; echo
declare -A index=([A]=0 [b]=1 [c]=2 [u]=3)
while IFS=: read -r -a font; do
for ((i=0; i<${#text}; i )); do
char=${text:i:1}
glyph="${font[${index[$char]}]}"
printf %s "${glyph//W/$k}"
done
echo
done << 'EOF'
WW :W : : :
W W :WWW : WW :W W :
WWWW :W W :W :W W :
W W :WWW : WW : WWW :
EOF
Example usage
Enter text: bAcubA
Enter character style: @
@ @@ @ @@
@@@ @ @ @@ @ @ @@@ @ @
@ @ @@@@ @ @ @ @ @ @@@@
@@@ @ @ @@ @@@ @@@ @ @
Implementing the same thing in awk
, perl
or any other language would be way easier and more efficient than doing it in plain bash. But I think you already know this, and just see this as an exercise in bash. Otherwise you could have used banner
, figlet
, toilet
, or another tool like that.