Register
It is currently Sat Sep 20, 2014 8:02 pm

Replacing numbers with letters


All times are UTC - 6 hours


Post new topic Reply to topic  [ 6 posts ] 
Author Message
 PostPosted: Mon Apr 09, 2012 5:22 am   
User avatar

Joined: Mon Apr 09, 2012 5:12 am
Posts: 2
Hello all!

I have this assignment to make the following script:

INPUT:
./<scriptname> number1 number2 number3 number4
PROCESSING:
Look up all the possible combinations in /usr/share/dict/words while you replace '2' with an a, b or c, '3' with d, e or f,... like in a cellphone
OUTPUT:
Show matches or errormessage if no match

Sor far I have come up with this:
Code:
#!/bin/bash

if [[ $# -lt 1 ]]
then
   echo "No input was given. Please enter some numbers."
   exit
fi

while [[ $# -gt 0 ]]; do
   if [[ $1 =~ [^2-9] ]]
   then
      echo "Invalid input ($1). Only numbers between 2 and 9 are allowed."
      exit
   else
      number="$number $1"
      echo "$number"
      shift
   fi
done


But I'm having a lot of trouble finding out how to do the actual conversion from the numbers to the letters and searching them in the word list, that is without a ridicoulously long if-then-else-structure.

Note: as you might suspected by now, my level in shell scripting is very basic L-)


Top
 Profile  
 PostPosted: Mon Apr 09, 2012 8:30 am   

Joined: Mon Mar 02, 2009 3:03 am
Posts: 548
hi,

I'd use an array where I'd put regexes
Code:
cellkeys[2]="(a|b|c)"
aso

and use double square brackets with tilde
Code:
regex="^${cellkeys[$1]}${cellkeys[$2]}${cellkeys[$3]}"
while read word
do if [[ $word =~ $regex ]]
   then echo "$word"
   fi
done < /usr/share/dict/words
you may add a test to quit as soon as the first character is not cellkeys[$1].


Top
 Profile  
 PostPosted: Mon Apr 09, 2012 1:21 pm   
User avatar

Joined: Mon Apr 09, 2012 5:12 am
Posts: 2
Hello again,

Thanks for the reply, it has helped me a great deal. However, the script still fails to work properly. Currently, the code is
Code:
#!/bin/bash
# Script for tranlating numbers to letters and looking up the possible combinations in the dictionary


trans[2]="(a|b|c)"
trans[3]="(d|e|f)"
trans[4]="(g|h|i)"
trans[5]="(j|k|l)"
trans[6]="(m|n|o)"
trans[7]="(p|q|r|s)"
trans[8]="(t|u|v)"
trans[9]="(w|x|y|z)"

i=0
j=$#
while [[ $i -ne $j ]]
do
   if [[ $1 =~ [^2-9] ]]
   then
      echo "Invalid input ($1) on position $(($i + 1)). Only numbers between 2 and 9 are allowed."
      exit
   else
      regex="$regex\${trans[$1]}"
      i=$(($i + 1))
      shift
   fi
done

###
### ALL GOOD HERE
###

#Adding a ^ and a $ to only match the exact length
regex="^$regex\$"
echo $regex
#This gives for eg. 9 6 6 6
# ^${trans[9]}${trans[6]}${trans[6]}${trans[6]}$
#But I need to have
# ^(w|x|y|z)(m|n|o)(m|n|o)(m|n|o)$
# I tried $eval but then I get
# ^(w|x|y|z)(m|n|o)(m|n|o)(m|n|o)$: command not found

#Looking up all the combinations
while read word
do
   if [[ $word =~ $regex ]]
   then
      echo $word >> words.tmp
   fi
done < /usr/share/dict/words

count=$(wc -l words.tmp | sed 's/[^[:digit:]]//g')
echo $count

if [[ $count -gt 5 ]]
then
   echo "More than five matches. You can find the words in words.tmp"
elif [[ ! -e words.tmp ]]
   echo "No matching words."
#Weird thing here aswell, I get
# syntax error near unexpected token `else'
else
   cat words.tmp
fi
rm words.tmp


I have place the problems in comments.


Top
 Profile  
 PostPosted: Mon Apr 09, 2012 2:03 pm   

Joined: Mon Mar 02, 2009 3:03 am
Posts: 548
Code:
   else
      regex="$regex\${trans[$1]}"
why is there a backslash?
it will prevent the array item to expand to its value.

another thing:
Code:
wc -l <file
will give only the number of lines, without the filename.


Top
 Profile  
 PostPosted: Wed May 02, 2012 12:01 pm   
User avatar

Joined: Wed Jun 08, 2011 8:27 am
Posts: 189
Location: outer Shpongolia
What Watael has said.
Also, you're missing a then, after the elif statement.


Here is what I did:

Code:
#!/bin/bash

if [[ $* = *[![:digit:][:blank:]]* ]]; then
   cat >&2 << 'EOD'
          °
          |
          |
          |
  ________|__
/  ---------  \
|   _______   |
|  |I'm goi|  |
|  |ng to h|  |
|  |ang up |  |
|  |this ph|  |
|  |one... |  |
|  |_______|  |
|  o  (°)  o  |
|   _______   | 
|  | x 2 3 |  |
|  | 4 5 6 |  |
|  | 7 8 9 |  |
|  | x x x |  |
|   ```````   |
\_____________'

EOD

   printf 'usage: ./%s number1 number2 number3 ... numberN\n' "${0##*/}" >&2
   exit 1
fi

keys=( ''  ''
       abc def  ghi jkl
       mno pqrs tuv wxyz
     )

for num; do
   if ((num < 2 || num > 9)); then
      echo 'error: the numbers must be between 2 and 9, inclusive.' >&2
      exit 1
   fi
   
   pat+="[${keys[num]}]"
done

if ! grep -i "^${pat}$" /usr/share/dict/words; then
   echo 'No matches.'
   exit 1
fi


Top
 Profile  
 PostPosted: Fri Jul 06, 2012 3:28 am   

Joined: Fri Jul 06, 2012 3:08 am
Posts: 4
Another way of doing it...

Code:
#!/bin/bash

function get_letters
{
  case "$1" in
    [!2-9]* )   printf "invalid argument '$1'!\n"
                exit 1
                ;;
  esac

  keymap[2]="[abc]"
  keymap[3]="[def]"
  keymap[4]="[ghi]"
  keymap[5]="[jkl]"
  keymap[6]="[mno]"
  keymap[7]="[pqrs]"
  keymap[8]="[tuv]"
  keymap[9]="[wxyz]"

  __get_letters=${keymap["$1"]}
  return 0
}


dict_file=/usr/share/dict/words
script_name="${0##*/}"


if [[ -z "$@" ]]
then
printf "usage: $script_name n <n> <n> <n> ...\n"
exit 0
fi

for n in $@
do
  get_letters "$n"
  word_re="${word_re}$__get_letters"
done

word_re_len=$#
while read actual_word
do
  if [ ${#actual_word} -eq $word_re_len ]
  then
    [[ "$actual_word" =~ $word_re ]] && printf "$actual_word\n"
  fi
done < "$dict_file"



Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], Majestic-12 [Bot], Watael and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP