(Shell Script) Set value of numbers from current time
Im trying to make a shell script to take the output from the current time (HH:MM) and assign a variable (font) to each number 0-9. This essentially is a clock, which I need to run in realtime (changes when the time changes). for example if I run this command:
date +"%T"
I will get an output (results may vary):
12:30:27
How can I make it so instead it will output this (without the "seconds")
_ ____ _____ ___
/ |___ \ _ |___ / / _ \
| | __) | (_) |_ \| | | |
| |/ __/ _ ___) | |_| |
|_|_____| (_) |____/ \___/
The only way I can think of achieving this is by assigning the numbers individually with the font being used. The link to the font i am using is:
http://patorjk.com/software/taag/#p=display&f=Standard&t=12%20%3A%2030
Is there anyway I can output the time (in realtime) using numbers like this?
To show a realtime ASCII art clock, use
watch 'date "+%H:%M" | figlet'
to save the current time in a variable, use
myVariable="$(date "+%H:%M" | figlet)"
As long as your cursor is not at the bottom of the screen, and you are in a terminal emulator that supports these cursor motions:
#!/bin/sh
f() { echo -n "\\033[$1D\\033[1B"; }
_c=" _$(f 2)(_)$(f 2)_$(f 2)(_)$(f 1) "
_0=" ___$(f 4)/ _ \\ $(f 7)| | | |$(f 7)| |_| |$(f 6)\\___/ "
_1=" _$(f 2)/ |$(f 3)| |$(f 3)| |$(f 3)|_| "
_2=" ____$(f 5)|___ \\ $(f 5)__) | $(f 7)/ __/ $(f 8)|_____| "
_3=" _____$(f 6)|___ / $(f 7) |_ \\ $(f 7) ___) | $(f 9)|____/ "
_4=" _ _ $(f 10) | || | $(f 10) | || |_ $(f 10) |__ _| $(f 7) |_| "
_5=" ____ $(f 9) | ___| $(f 9) |___ \ $(f 9) ___) | $(f 9) |____/ "
_6=" __ $(f 9) / /_ $(f 9)| '_ \ $(f 9)| (_) | $(f 9) \___/ "
_7=" _____ $(f 9) |___ | $(f 9) / / $(f 9) / / $(f 9) /_/ "
_8=" ___ $(f 9) ( _ ) $(f 9) / _ \ $(f 9)| (_) |$(f 9) \___/ "
_9=" ___ $(f 9) / _ \ $(f 9) | (_) |$(f 9) \__, |$(f 7) /_/ "
eval echo -e '"'$(date +"%T" | tr : c | cut -b 1-5 | sed 's/./${_&}\\033[4A/g')'"'
echo -e "\\033[5B"
Try this:
Host#User> date +"%H:%M"
09:47
Host#User>
Related
Currently I have this kind of output format:
{ echo "$(figlet buddhi)"; echo "$(figlet lw)"; }
_ _ _ _ _
| |__ _ _ __| | __| | |__ (_)
| '_ \| | | |/ _` |/ _` | '_ \| |
| |_) | |_| | (_| | (_| | | | | |
|_.__/ \__,_|\__,_|\__,_|_| |_|_|
_
| |_ __
| \ \ /\ / /
| |\ V V /
|_| \_/\_/
And I would like to have this output format:
figlet buddhi lw
_ _ _ _ _ _
| |__ _ _ __| | __| | |__ (_) | |_ __
| '_ \| | | |/ _` |/ _` | '_ \| | | \ \ /\ / /
| |_) | |_| | (_| | (_| | | | | | | |\ V V /
|_.__/ \__,_|\__,_|\__,_|_| |_|_| |_| \_/\_/
The reason is: I would like to color each name (buddhi, lw) with a different color. But, retain the format of a continuous string, or at maximum space-separated, as above.
Example:
#COMMANDS CREATED INSIDE /ETC/BASH.BASHRC FILE
# USING ANSI COLORS
RED="\e[31m"
ORANGE="\e[33m"
BLUE="\e[94m"
GREEN="\e[92m"
STOP="\e[0m"
printf "${GREEN}"
printf "=================================\n"
printf "${ORANGE}"
figlet -f standard "Buddhi"
printf "${BLUE}"
figlet -f small "LW"
printf "${GREEN}"
printf "=================================\n"
printf "${STOP}"
Store the lines of each word in arrays, output both the arrays line by line. As the first line of "Buddhi" seems to be one character shorter, I stored the longest line length of the first word in a variable, and used the %-s format to pad each line.
#! /bin/bash
RED="\e[31m"
ORANGE="\e[33m"
BLUE="\e[94m"
GREEN="\e[92m"
STOP="\e[0m"
mapfile -t left < <(figlet -f standard "Buddhi")
mapfile -t right < <(figlet -f small "LW")
maxlength=0
for line in "${left[#]}" ; do
if (( ${#line} > maxlength )) ; then
maxlength=${#line}
fi
done
printf "${GREEN}"
printf "=================================\n"
for ((i=0; i<=${#left[#]}; ++i)) ; do
printf "${ORANGE}%-${maxlength}s ${GREEN}%s\n" "${left[i]}" "${right[i]}"
done
printf "${GREEN}"
printf "=================================\n"
printf "${STOP}"
If you need a shorter version:
printf "$GREEN=================================\n"
{ figlet Buddhi; echo 'EOF'; figlet LW; } | awk 'NF==1&&$1=="EOF" {noskip=1; next; } noskip==0 { f[++c]=$0; next; } { printf "%s%s%s%s\n","'"$ORANGE"'",f[++k],"'"$BLUE"'",$0;}'
printf "$GREEN=================================\n"
tput sgr0
I would recommend to use tput for setting the color as not every terminal will know your escape sequences
The guys who invented shell also invented awk for shell to call to manipulate text. Those escape sequences don't change colors on my terminal, they just show up as-is (fortunately so you can see where the script is puting them):
$ cat tst.sh
#!/usr/bin/env bash
awk '
BEGIN {
red = "\\e[31m"
orange = "\\e[33m"
blue = "\\e[94m"
green = "\\e[92m"
stop = "\\e[0m"
}
{
val[(NR==FNR),FNR] = $0
}
NR == FNR {
wid = length($0)
maxWid = ( wid > maxWid ? wid : maxWid )
}
END {
for ( lineNr=1; lineNr<=FNR; lineNr++ ) {
printf "%s%-*s%s%s%s\n", orange, maxWid, val[1,lineNr], blue, val[0,lineNr], stop
}
}
' <(cat Buddhi) <(cat LW)
$ ./tst.sh
\e[33m _ _ _ _ _ \e[94m _\e[0m
\e[33m| |__ _ _ __| | __| | |__ (_)\e[94m| |_ __\e[0m
\e[33m| '_ \| | | |/ _` |/ _` | '_ \| |\e[94m| \ \ /\ / /\e[0m
\e[33m| |_) | |_| | (_| | (_| | | | | |\e[94m| |\ V V /\e[0m
\e[33m|_.__/ \__,_|\__,_|\__,_|_| |_|_|\e[94m|_| \_/\_/\e[0m
Since I don't have figlet, I ran the above on these files:
$ head Buddhi LW
==> Buddhi <==
_ _ _ _ _
| |__ _ _ __| | __| | |__ (_)
| '_ \| | | |/ _` |/ _` | '_ \| |
| |_) | |_| | (_| | (_| | | | | |
|_.__/ \__,_|\__,_|\__,_|_| |_|_|
==> LW <==
_
| |_ __
| \ \ /\ / /
| |\ V V /
|_| \_/\_/
Just change the last line of the script from:
' <(cat Buddhi) <(cat LW)
to
' <(figlet Buddhi) <(figlet LW)
to use actual figlet output.
the above assumes you only have 2 figlet output strings to concatenate and that both sets of output are the same length, it's easy tweaks if either of those assumptions is wrong.
In lieu of figlet I'll use the following as my inputs:
$ cat buddhi
_ _ _ _ _
| |__ _ _ __| | __| | |__ (_)
| '_ \| | | |/ _` |/ _` | '_ \| |
| |_) | |_| | (_| | (_| | | | | |
|_.__/ \__,_|\__,_|\__,_|_| |_|_|
$ cat lw
_
| |_ __
| \ \ /\ / /
| |\ V V /
|_| \_/\_/
Assuming figlet generates the same number of output lines for each input string, we can use paste (# as a delimiter) and a while/read loop to generate the desired output:
printf "${GREEN}"
printf "============================\n"
maxwidth=$(awk '{max=length($0) > max ? length($0) : max}END{print max}' buddhi)
while IFS='#' read -r col1 col2
do
printf "${ORANGE}%-*s ${BLUE}%s\n" "${maxwidth}" "${col1}" "${col2}"
done < <(paste -d"#" buddhi lw)
printf "${GREEN}"
printf "============================\n"
This generates:
Expanding to 3 input streams:
printf "${GREEN}"
printf "============================\n"
max1=$(awk '{max=length($0) > max ? length($0) : max}END{print max}' buddhi)
max2=$(awk '{max=length($0) > max ? length($0) : max}END{print max}' lw)
while IFS='#' read -r col1 col2 col3
do
printf "${ORANGE}%-*s ${BLUE}%-*s ${RED}%s\n" "${max1}" "${col1}" "${max2}" "${col2}" "${col3}"
done < <(paste -d"#" buddhi lw buddhi)
printf "${GREEN}"
printf "============================\n"
This generates:
Using coordinates
#!/bin/bash
RED='\e[31m'
GRN='\e[32m'
XY(){ printf "\e[$2;${1}H$3"; }
mapfile -t frst < <(figlet -f standard "Buddhi")
mapfile -t scnd < <(figlet -f small "LW")
XY 1 1 "$GRN==============================================="; y=2
for line in "${frst[#]}"; { XY 0 $y "$RED$line"; ((y++)); }; y=2
for line in "${scnd[#]}"; { XY 35 $y "$GRN$line"; ((y++)); }
XY 1 8 "$GRN==============================================="
More examples here, here and here
I want to generate a English word with pure characters like |, /, \, (, ) etc. in my code comments.
For example,
_
(_)
__ __ __ _ ___ ___ _
\ \ / / / _` | / __| / __| | |
\ V / | (_| | | (__ | (__ | |
\_/ \__,_| \___| \___| |_|
I wonder if there is a tool that automatically does the job? I don't know how to properly google it.
This tool might be helpful: https://patorjk.com/software/taag/#p=display&h=1&v=1&f=Big&t=vaccine
You can choose your favorite font, character width/height, and copy the wonderful ASCII art to your clipboard.
I have a logo which I want to print/echo using bash in console, through scripts, but I can't even paste here properly(looks good inside .txt file):
___ _____ _ _ _____ _ _ ___
| _| / ___| | | || ___| \ | | |_ |
| | \ `--.| |_| || |__ | \| | | |
| | `--. \ _ || __|| . | | |
| | /\__/ / | | || |___| |\ | | |
| |_ \____/\_| |_/\____/\_| \_/ _| |
|___| |___|
How I can do that properly and make it colour without 3rd party extensions?
Also, is it possible to print it from the file?
You may use tput:
tput setaf 2; cat logo.txt
2 is the color code here (red). These are the available codes:
Value Color
0 Black
1 Red
2 Green
3 Yellow
4 Blue
5 Magenta
6 Cyan
7 White
8 Not used
9 Reset to default color
I'm trying to use echo in bash inside of quotes.
When I try from a command line, it works fine.
For example: echo "I'm testing the apostrophe functionality."
yields I'm testing the apostrophe functionality.
Yet, when I write this in a script, it doesn't seem to work.
Here's a snippet of my code: (I'm trying to integrate ASCII art into my program)
if [ "$2" == "-s" ]
then echo " ___ __ _ _ "
echo " / _ \__ _ _ __ ___ ___ / _\ |_ __ _ _ __| |_ ___ _ __ "
echo " / /_\/ _` | '_ ` _ \ / _ \_____\ \| __/ _` | '__| __/ _ \ '__|"
echo "/ /_\\ (_| | | | | | | __/_____|\ \ || (_| | | | || __/ | "
echo "\____/\__,_|_| |_| |_|\___| \__/\__\__,_|_| \__\___|_| "
echo ""
echo "Hello! My name is Siri."
echo "I'm not actually the Siri you're probably used to."
echo "I'm actually Apple's Siri's sister, the no-voice one."
echo "Sorry, but I'm in development right now."
echo "Come back later and maybe Eric will bring me out of beta."
echo "Thanks for reading this long debug message!"
fi
I've checked and double-checked all my quotes...
Yet it still yields:
./game-starter.sh: line 7: unexpected EOF while looking for matching ``'
./game-starter.sh: line 88: syntax error: unexpected end of file
Please help soon!
-HewwoCraziness
As you're using double quotes around your strings, certain characters are interpreted by the shell. One example is the backtick, as mentioned in Ryan's answer.
One option would be to use single quotes around your strings, although then you would have to escape the apostrophes in your message. I think that the best solution would be to use a heredoc instead:
cat <<'EOF'
___ __ _ _
/ _ \__ _ _ __ ___ ___ / _\ |_ __ _ _ __| |_ ___ _ __
/ /_\/ _` | '_ ` _ \ / _ \_____\ \| __/ _` | '__| __/ _ \ '__|
/ /_\\ (_| | | | | | | __/_____|\ \ || (_| | | | || __/ |
\____/\__,_|_| |_| |_|\___| \__/\__\__,_|_| \__\___|_|
Hello! My name is Siri.
I'm not actually the Siri you're probably used to.
I'm actually Apple's Siri's sister, the no-voice one.
Sorry, but I'm in development right now.
Come back later and maybe Eric will bring me out of beta.
Thanks for reading this long debug message!
EOF
The quotes around the EOF mean that the string is interpreted literally, so characters such as | don't cause problems.
I don't think it's the apostrophes that are causing your issue; is it the ` character (you know, on the ~ key). It is used for running commands in place and other things, and is probably what's causing the issue, if I had to guess based on that error message.
I get these errors when trying to use: export PS1='ascii text at bottom'.
bash: command substitution: line 1: syntax error near unexpected token |'
bash: command substitution: line 1:/ ^ \ | |_) |'
bash: command substitution: line 3: syntax error near unexpected token |'
bash: command substitution: line 3: \ /\ / / _____ \ | |\ ---) |'
Could someone explain why this doesn't work?
________________. ___ .______
/ | / \ | _ \
| (-----| |----`/ ^ \ | |_) |
\ \ | | / /_\ \ | /
.------) | | | / _____ \ | |\ \-------.
|_________/ |__| /__/ \__\| _| `.________|
____ __ ____ ___ .______ ________.
\ \ / \ / / / \ | _ \ / |
\ \/ \/ / / ^ \ | |_) || (-----`
\ / / /_\ \ | / \ \
\ /\ / / _____ \ | |\ \---) |
\__/ \__/ /__/ \__\|__| `._______/
PS1 is not just a plain string; in it, certain characters have meaning to them. You can find a surprisingly long document telling you more about bash prompts than you ever wanted to know here; it's a bit dated, but most of it should still hold. The particular problem you run into is that backslashes and backticks need to be escaped -- backslashes because they're used to escape things, and backticks because they're used for command substitutions -- and newlines are best replaced with the \n control sequence to avoid mishaps with lines that end in \. Ultimately, you want the effect of writing
export PS1=' ________________. ___ .______ \n / | / \\ | _ \\\n | (-----| |----\`/ ^ \\ | |_) |\n \\ \\ | | / /_\\ \\ | /\n.------) | | | / _____ \\ | |\\ \\-------.\n|_________/ |__| /__/ \\__\\| _| \`.________|\n____ __ ____ ___ .______ ________.\n\\ \\ / \\ / / / \\ | _ \\ / |\n \\ \\/ \\/ / / ^ \\ | |_) || (-----\`\n \\ / / /_\\ \\ | / \\ \\\n \\ /\\ / / _____ \\ | |\\ \\---) |\n \\__/ \\__/ /__/ \\__\\|__| \`._______/'
...which is somewhat unwieldy. A way to do this on the fly so that it is easier on the eyes is
PS1=' ________________. ___ .______
/ | / \ | _ \
| (-----| |----`/ ^ \ | |_) |
\ \ | | / /_\ \ | /
.------) | | | / _____ \ | |\ \-------.
|_________/ |__| /__/ \__\| _| `.________|
____ __ ____ ___ .______ ________.
\ \ / \ / / / \ | _ \ / |
\ \/ \/ / / ^ \ | |_) || (-----`
\ / / /_\ \ | / \ \
\ /\ / / _____ \ | |\ \---) |
\__/ \__/ /__/ \__\|__| `._______/'
PS1="${PS1//\\/\\\\}"
PS1="${PS1//\`/\\\`}"
PS1="${PS1//
/\\n}"
export PS1 # <-- this isn't really necessary, by the way. PS1 is not
# usually used by processes the shell spawns.
Here ${variable//pattern/replacement} is a bash-specific parameter expansion that expands to the value of $variable with all occurrences of pattern replaced with replacement. That is to say:
PS1="${PS1//\\/\\\\}" # replaces \ with \\
PS1="${PS1//\`/\\\`}" # replaces ` with \`
PS1="${PS1// # replaces newlines with \n
/\\n}"