I have a code.txt file that contains morse code for example
.- .-.
I have a function called decode inside a bash file called morse as this:
decode (){
sed -i 's/ \.-/A/g' $1
sed -i 's/ \.-./R/g' $1
cat $1
}
When I type in terminal $bash morse decode code.txt
I receive:
AA.
The output I want is :
AR
How can it see separate that the string .- is A and the .-. is R ?
If your intention is to encode and decode Morse messages with any tool then something like this will do :
#!/usr/local/bin/python3
import re
alphabet = { 'A':'.-', 'B':'-...', 'C':'-.-.', 'D':'-..', 'E':'.', 'F':'..-.', 'G':'--.', 'H':'....', 'I':'..', 'J':'.---', 'K':'-.-', 'L':'.-..', 'M':'--', 'N':'-.', 'O':'---', 'P':'.--.', 'Q':'--.-', 'R':'.-.', 'S':'...', 'T':'-', 'U':'..-', 'V':'...-', 'W':'.--', 'X':'-..-', 'Y':'-.--', 'Z':'--..', '1':'.----', '2':'..---', '3':'...--', '4':'....-', '5':'.....', '6':'-....', '7':'--...', '8':'---..', '9':'----.', '0':'-----', ', ':'--..--', '.':'.-.-.-', '?':'..--..', '/':'-..-.', '-':'-....-', '(':'-.--.', ')':'-.--.-',' ':' '}
def encode(message):
return "".join([ ( alphabet[letter.upper()] + ' ' ) if letter != ' ' else ' ' for letter in message])
def decode(message):
return "".join([ list(alphabet.keys())[list(alphabet.values()).index(item if item != '|' else ' ')] for item in re.sub(r' {2,}', ' | ',message).split(' ')])
print(encode('THIS IS FINE'))
print(decode('- .... .. ... .. ... ..-. .. -. .'))
Hope it helps too.
Wow interesting idea! Based on @MatiasBarrios alphabet i made this.
#!/bin/bash
string=$1
declare -A morse=(
[A]='.-' [B]='-...' [C]='-.-.' [D]='-..' [E]='.'
[F]='..-.' [G]='--.' [H]='....' [I]='..' [J]='.---'
[K]='-.-' [L]='.-..' [M]='--' [N]='-.' [O]='---'
[P]='.--.' [Q]='--.-' [R]='.-.' [S]='...' [T]='-'
[U]='..-' [V]='...-' [W]='.--' [X]='-..-' [Y]='-.--'
[Z]='--..'
[1]='.----' [2]='..---' [3]='...--' [4]='....-' [5]='.....'
[6]='-....' [7]='--...' [8]='---..' [9]='----.' [0]='-----'
[(]='-.--.' [)]='-.--.-' [/]='-..-.' [-]='-....-' [+]='.-.-.'
[.]='.-.-.-' [,]='--..--' [?]='..--..' [!]='-.-.--' [ ]=' '
)
morse () {
while [[ "$string" ]]; do
symbol="${string::1}"
printf -- "${morse["${symbol^}"]} "
string="${string:1}"
done
}
demorse () {
declare -A demorse
for item in "${!morse[@]}"; { demorse["${morse["$item"]}"]="$item"; }
while [[ $@ ]]; do
printf -- "${demorse["$1"],}"
shift
done
}
case $string in
demorse) shift; demorse "$@";;
* ) morse ;;
esac
Usage
$ ./morse 'hello world!'
.... . .-.. .-.. --- .-- --- .-. .-.. -.. -.-.--
Demorse also worsk but, spaces have to be printed like this ' '
$ ./morse demorse .... . .-.. .-.. --- ' ' .-- --- .-. .-.. -.. -.-.--
hello world!
You need to run s/ \\.-\\./R/g
replacement first. Note the second .
must be escaped to only match a dot.
Hence, use
sed 's/ \.-\./R/g;s/ \.-/A/g' file
See the online demo
Or, another way:
sed -e 's/ \.-\./R/g' -e 's/ \.-/A/g' file
Replace the file
with "$1"
in your code.
UPDATE
Here is the translation of encoding / decoding Python function posted by Matias below:
#!/bin/bash
### Encoding:
declare -A MORSE=( [A]='.-' [B]='-...' [C]='-.-.' [D]='-..' [E]='.' [F]='..-.' [G]='--.' [H]='....' [I]='..' [J]='.---' [K]='-.-' [L]='.-..' [M]='--' [N]='-.' [O]='---' [P]='.--.' [Q]='--.-' [R]='.-.' [S]='...' [T]='-' [U]='..-' [V]='...-' [W]='.--' [X]='-..-' [Y]='-.--' [Z]='--..' [1]='.----' [2]='..---' [3]='...--' [4]='....-' [5]='.....' [6]='-....' [7]='--...' [8]='---..' [9]='----.' [0]='-----' [',']='--..--' ['.']='.-.-.-' [';']='-.-.-.' [':']='---...' ['?']='..--..' ['!']='-.-.--' ['/']='-..-.' ['-']='-....-' ['+']='.-.-.' ['(']='-.--.' [')']='-.--.-' ['_']='..--.-' ['"']='.-..-.' ["'"]='.----.' ['$']='...-..-' ['@']='.--.-.' ['&']='.-...' [' ']=' ' )
function encode {
res=''
s="$1"
for (( i=0; i<${#s}; i++ )); do
letter="${s:$i:1}"
if [[ "$letter" == ' ' ]]; then
res="${res} "
else
res="${res}${MORSE[${letter^^}]} ";
fi
done
printf "%s" "$res"
}
echo "$(encode "THIS IS FINE")"
### Now, decoding
declare -A MORSEDEC=( ['-.--.-']=')' ['..--..']='?' ['--..--']=', ' ['-....-']='-' ['.-.-.-']='.' ['...--']='3' ['-.--.']='(' ['---..']='8' ['-..-.']='/' ['....-']='4' ['-....']='6' ['----.']='9' ['.----']='1' ['..---']='2' ['.....']='5' ['--...']='7' ['-----']='0' ['-...']='B' ['-..-']='X' ['-.-.']='C' ['--..']='Z' ['--.-']='Q' ['.-..']='L' ['-.--']='Y' ['..-.']='F' ['.--.']='P' ['.---']='J' ['...-']='V' ['....']='H' ['-..']='D' ['---']='O' ['..-']='U' ['...']='S' ['.--']='W' ['-.-']='K' ['.-.']='R' ['--.']='G' ['-.']='N' ['..']='I' ['--']='M' ['.-']='A' [' ']=' ' ['.']='E' ['-']='T' )
function decode {
res=''
tmp="$(sed 's/ \{2,\}/ | /g' <<< "$1")";
for word in $tmp; do
if [[ "$word" == '|' ]]; then
res="${res}${MORSEDEC[' ']}";
else
res="${res}${MORSEDEC[$word]}";
fi
done
printf "%s" "$res"
}
echo "$(decode "- .... .. ... .. ... ..-. .. -. .")"
See Bash demo online .
The easy answer in RE engines that support look-ahead and look-behind would be to treat the spaces as look-ahead and look-behind triggers, but sed does not support this.
Another option that avoids needing to order the letters is to inject extra symbols to help you mark each letter. Say we inject = round each space, then we can replace delimited sequences in any order, and finally get rid of the delimiters:
echo .- .-.|sed -e 's/^\(.*\)$/=\1=/;s/ /= =/g' -e 's/=\.-\.=/=R=/g;s/=\.-=/=A=/g' -e 's/= =//g;s/^=//;s/=$//'
If you have rules that need to preserve multiple spaces, then that can be accommodated.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.