1

I'm trying to practice code and integrating my other interests with it, and a strong interest of mine is genetics/science in general. I'm making a simple script to generate a random string, but if I use the input for a genetic code (AGCT), the cat output will be colored according to the letters (A - blue, G - green, C - red, T - yellow). I was scratching my head for a while on it, and my google-fu isn't very good. An output from the command (using the genetic code input) looks like this:

user@conroe$ random AGCT 128
TTCAGGATCAGGTGGCCGATGCCCGTCACGTAGTGGAGGTATTACGTTTTCATCAATCACACGTTACCCCACTTCCTAGCGACAACGTGTGACTCGATGAATAGGAGCAGCGTCCCGCTCGAGATGAC

And this is the code:

RED='\033[0;31m'
NC='\033[0m'
if [ $# == 2 ]
then
    { cat /dev/urandom | env LC_CTYPE=C tr -dc $1 | head -c $2; echo; }
    else
        printf "${RED}error: ${NC}insufficient input\n"
fi

Any help?

4
  • You can just pipe to sed as: random AGCT 128 | sed "s/A/${BLUE}A${NC}/" | sed "s/G/${GREEN}G${NC}/" and so on ...
    – Bichoy
    Jun 17, 2015 at 4:29
  • I'm not sure if I understand what you want to do. You want to color the output to the letter A with blue, G with green and so on?
    – VaTo
    Jun 17, 2015 at 4:56
  • @SaulOrtega Yep! Jun 17, 2015 at 5:01
  • Why the superfluous cat? You should just do < /dev/urandom env LC_TYPE=C tr -dc $1 | ....
    – Anthon
    Jun 17, 2015 at 5:52

1 Answer 1

1

You can pipe the output of < /dev/urandom tr -dc $1 | head -c $2 (I took the liberty of removing the UUOC and the apparently unneeded env LC_CTYPE=C and echo; you can restore them in your version however) to a while loop reading one character at the time and echoing different color escape sequences followed by a different character based on the read character:

#!/bin/bash

if [ $# == 2 ]
then
    < /dev/urandom tr -dc $1 | head -c $2 | while read -n 1 x
    do
        case $x in
            A)
                echo -ne '\033[0;34mA'
            ;;
            G)
                echo -ne '\033[0;32mG'
            ;;
            C)
                echo -ne '\033[0;31mC'
            ;;
            T)
                echo -ne '\033[0;33mT'
            ;;
        esac
    done
    echo -e '\033[0m'
    exit 0
fi
exit 1

screenshot

11
  • 1
    Don't hardcode escape sequences, use tput which gets them from the current terminal definition: tput setaf 4; echo -n A, tput setaf 2; echo -n G, etc...
    – Celada
    Jun 17, 2015 at 5:27
  • It works, but I was looking for something that was only in one line. This splits it up and prints a new character each line. Jun 17, 2015 at 5:29
  • @ViktorAhlström This prints everything in only one line followed by a single newline at the end. Are you sure you copied the script exactly like it is? Also it's meant to be run in bash. Which shell are you using?
    – kos
    Jun 17, 2015 at 5:34
  • I'm using zsh, oops. Jun 17, 2015 at 5:40
  • 1
    @Celada It's more complicated that that. On OpenBSD: tput setaf 3 - tput: not enough arguments (3) for capability `setaf'; echo $TERM - xterm-256color; infocmp -1 | grep setaf - setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
    – lcd047
    Jun 17, 2015 at 5:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.