skip to Main Content

I have some ascii banners saved to plain text files that I use for different things and have used various ways to randomize the colors, but I haven’t come up with a way to give every character a different color yet. I’m thinking there’s probably a way to do an array to make it happen, but can’t seem to quite get there – I’m aware of things like toilet and lolcat but I’m not able to use those currently (using centos). Here’s what I’ve done so far:

change each file to a random color:

echo -e "e[38;5;$(shuf -i 1-255 -n 1)m$(<ascii/gc)e[0m"

you can do this with $RANDOM too:

echo -e "e[38;5;$(( $RANDOM % 256 ))m$(<ascii/gc)e[0m"

change each line in the file to a different color:

while IFS= read -r line; do
echo -e "e[38;5;$(shuf -i 1-255 -n 1)m${line}e[0m";
done<ascii/gc

These files use multiple rows like so:

 $$$$$$                            $$        $$$$$$  $$                 $$                     $$
$$  __$$                           $$ |      $$  __$$ $$ |                __|                    $$ |
$$ /  __| $$$$$$   $$$$$$   $$$$$$$ |      $$ /  __|$$$$$$$   $$$$$$  $$  $$$$$$$  $$$$$$  $$ |
$$ |$$$$ $$  __$$ $$  __$$ $$  __$$ |      $$ |      $$  __$$ $$  __$$ $$ |$$  _____|$$  __$$ $$ |
$$ |_$$ |$$ /  $$ |$$ /  $$ |$$ /  $$ |      $$ |      $$ |  $$ |$$ /  $$ |$$ |$$ /      $$$$$$$$ |__|
$$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |      $$ |  $$ $$ |  $$ |$$ |  $$ |$$ |$$ |      $$   ____|
$$$$$$  |$$$$$$  |$$$$$$  |$$$$$$$ |      $$$$$$  |$$ |  $$ |$$$$$$  |$$ |$$$$$$$ $$$$$$$ $$
 ______/  ______/  ______/  _______|       ______/ __|  __| ______/ __| _______| _______|__|

Thanks in advance!

3

Answers


  1. You can simply read character by character instead of line by line:

    echo "Hello World" > file
    # Read 1 character
    while IFS= read -r -n 1 -d '' char; do
      # Write character without linefeed
      echo -ne "e[38;5;$(shuf -i 1-255 -n 1)m${char}e[0m";
    done < file
    

    This is faster and more robust with printf and RANDOM:

    while IFS= read -r -n 1 -d '' c
    do
      printf 'e[38;5;%dm%se[0m' "$((RANDOM%255+1))" "$c"
    done < file
    
    Login or Signup to reply.
  2. My interpretation was printing each block letter in a different color. It required adding a separator to the input file (It looks the same, but I actually inserted zero-width space characters).

     $$$$$$  ​          ​          ​      $$ ​      ​ $$$$$$  ​$$       ​          ​$$ ​          ​          ​$$ ​
    $$  __$$ ​          ​          ​      $$ |​      ​$$  __$$ ​$$ |      ​          ​__|​          ​          ​$$ |​
    $$ /  __|​ $$$$$$  ​ $$$$$$  ​ $$$$$$$ |​      ​$$ /  __|​$$$$$$$  ​ $$$$$$  ​$$ ​ $$$$$$$ ​ $$$$$$  ​$$ |​
    $$ |$$$$ ​$$  __$$ ​$$  __$$ ​$$  __$$ |​      ​$$ |      ​$$  __$$ ​$$  __$$ ​$$ |​$$  _____|​$$  __$$ ​$$ |​
    $$ |_$$ |​$$ /  $$ |​$$ /  $$ |​$$ /  $$ |​      ​$$ |      ​$$ |  $$ |​$$ /  $$ |​$$ |​$$ /      ​$$$$$$$$ |​__|​
    $$ |  $$ |​$$ |  $$ |​$$ |  $$ |​$$ |  $$ |​      ​$$ |  $$ ​$$ |  $$ |​$$ |  $$ |​$$ |​$$ |      ​$$   ____|​    ​
    $$$$$$  |​$$$$$$  |​$$$$$$  |​$$$$$$$ |​      ​$$$$$$  |​$$ |  $$ |​$$$$$$  |​$$ |​$$$$$$$ ​$$$$$$$ ​$$ ​
     ______/ ​ ______/ ​ ______/ ​ _______|​      ​ ______/ ​__|  __|​ ______/ ​__|​ _______|​ _______|​__|​
    

    Then an awk one-liner can put color markings before and after each field, separated by the ZWS: 'xe2x80x8b'. It was necessary to use an external seed to get different colors at each run.

    awk -v seed=$RANDOM -F 'xe2x80x8b' 'BEGIN {srand(seed);} {for(i=1;i<=NF;i++){if(NR==1) {r[i]=int(rand()*255+1);} printf("33[38;5;%dm%s33[0m",r[i], $i);} printf("n");}' ascii/gc
    

    Here is the awk script expanded with comments:

    BEGIN { # this block runs before processing the input
        srand(seed); # use the random seed passed via command line
    }
    { # this block runs for each line
        for(i=1;i<=NF;i++) { # this block runs for each field
            if(NR==1) { # this block runs for the first line only
                r[i]=int(rand()*255+1); # generate a color for the field
            }
            printf("33[38;5;%dm%s33[0m",r[i], $i); # print the escape codes and the field 
        }
        printf("n"); # end of the line
    }
    

    It looks like this:

    random colored output from five runs

    Login or Signup to reply.
  3. In bash, you need to use color escape sequences with echo -e
    And you can use $RANDOM is an internal Bash function (not a constant) that returns a pseudorandom [1] integer in the range 0 – 32767.

    echo -e "e[3$(( $RANDOM * 6 / 32767 + 1 ))mHello World!"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search