Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- function die {
- echo -e "\e[31mERROR:\e[0m $2" >&2
- exit $1
- }
- function usage {
- echo "USAGE: $(basename $0) [-r] FILE"
- echo " $(basename $0) [-r] - <<<SEQUENCE"
- echo " $(basename $0) -R STRING"
- }
- function debug {
- if [ "$DEBUG_MODE" = "1" ]; then
- echo -e "\e[35mDEBUG: $*\e[m" >&2
- fi
- }
- function acgt-conv {
- tr -d '[:space:]' | while \
- # Read 4 chars from stdin (cut out whitespace first)
- read -r -N 4 BYTE ; do
- # Prepend with trailing T's (0s) from $FILL
- # For convenience we're doing little-endian here
- FILL=tttt
- BYTE="${BYTE}${FILL:${#BYTE}}"
- VAL=0
- for (( i=0 ; i < ${#BYTE} ; i++ )); do
- g=${BYTE:$i:1}
- # A=1 C=2 G=3 T=0
- case $g in
- A|a) VAL=$(( $VAL + (1 << ($i * 2)) )) ;;
- C|c) VAL=$(( $VAL + (2 << ($i * 2)) )) ;;
- G|g) VAL=$(( $VAL + (3 << ($i * 2)) )) ;;
- T|t) ;;
- *) die 2 "Format Error: Invalid DNA '$g' in byte '$BYTE'" ;;
- esac
- done
- if (( $VAL > 255 )); then
- die 3 "Math Error: Byte '$BYTE' produced out-of-range value '$VAL'"
- fi
- # Convert decimal number to character byte (in whatever encoding, only ASCII values matter here anyways)
- # It's around here I realize this probably should've been a C program...
- printf "\x$(printf %x $VAL)"
- # Testing: GTGA (little-endian) == AGTG (big-endian) == 115 == 0x73 == 's'
- done
- }
- # string to DNA
- function acgt-reverse {
- while read -rs -n 1 CHAR ; do
- # Convert char to hex, then hex to decimal
- HEX=$(printf "$CHAR" | od -An -t x1 | tr -d ' ')
- VAL=$(( 0x$HEX ))
- if (( $VAL > 255 )); then
- die 2 "Format Error: Character '$CHAR' produced multiple bytes. Only ASCII characters are supported."
- fi
- DNA=
- for (( i=0 ; i < 4 ; i++ )); do
- REM=$(( $VAL % 4 ))
- # A=1 C=2 G=3 T=0
- case $REM in
- 1) DNA="${DNA}A" ;;
- 2) DNA="${DNA}C" ;;
- 3) DNA="${DNA}G" ;;
- 0) DNA="${DNA}T" ;;
- esac
- VAL=$(( $VAL >> 2 ))
- done
- printf "$DNA "
- done
- }
- if [ -z "$1" ]; then
- usage >&2
- exit 1
- elif [[ "$1" = "-h" || "$1" = "--help" ]]; then
- usage
- exit 0
- elif [[ "$1" = "-T" || "$1" = "--test" ]]; then
- DEBUG_MODE=1
- shift
- elif [[ "$1" = "-R" || "$1" = "--reverse" ]]; then
- REVERSE_MODE=1
- shift
- elif [[ "$1" = "-r" || "$1" = "--raw" ]]; then
- OUTPUT=cat
- shift
- else
- OUTPUT=strings
- fi
- if [ "$1" = "-" ]; then
- DNA_FILE=/dev/stdin
- else
- DNA_FILE="$1"
- fi
- if [ "$REVERSE_MODE" = "1" ]; then
- printf "$*" | acgt-reverse
- echo
- elif [ "$DEBUG_MODE" != "1" ]; then
- cat $DNA_FILE | acgt-conv | $OUTPUT
- fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement