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 '15 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 '15 at 4:56
  • @SaulOrtega Yep! – 智障的人 Jun 17 '15 at 5:01
  • Why the superfluous cat? You should just do < /dev/urandom env LC_TYPE=C tr -dc $1 | .... – Anthon Jun 17 '15 at 5:52
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 '15 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 '15 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 '15 at 5:34
  • I'm using zsh, oops. – 智障的人 Jun 17 '15 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 '15 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.