Замените заданную строку c, используя sed - PullRequest
3 голосов
/ 06 февраля 2020

У меня есть code.txt файл, который содержит азбуку Морзе, например

.- .-.

У меня есть функция с именем decode внутри bash файла с именем morse , например:

decode (){ 
   sed -i 's/ \.-/A/g' $1
   sed -i 's/ \.-./R/g' $1
   cat $1
}

Когда я печатаю в терминале $bash morse decode code.txt

Я получаю:

AA.

Требуемый вывод:

AR

Как отделить, что строка .- равна A , а .-. - R

Ответы [ 4 ]

1 голос
/ 06 февраля 2020

Ух интересная идея! Основываясь на алфавите @ MatiasBarr ios, я сделал это.

#!/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

Использование

$ ./morse 'hello world!'
.... . .-.. .-.. ---    .-- --- .-. .-.. -.. -.-.--

Сносим также, но пробелы должны быть напечатаны следующим образом ' '

$ ./morse demorse .... . .-.. .-.. --- '  ' .-- --- .-. .-.. -.. -.-.--
hello world!
1 голос
/ 06 февраля 2020

Если вы намереваетесь кодировать и декодировать сообщения Морзе с помощью любого инструмента, то что-то вроде этого подойдет:

#!/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('- .... .. ...   .. ...   ..-. .. -. .'))

Надеюсь, это тоже поможет.

1 голос
/ 06 февраля 2020

Сначала нужно запустить s/ \.-\./R/g замену. Обратите внимание, что вторая . должна быть экранирована, чтобы соответствовать только точке.

Следовательно, используйте

sed 's/ \.-\./R/g;s/ \.-/A/g' file

См. онлайн-демонстрацию

Или , иначе:

sed -e 's/ \.-\./R/g' -e 's/ \.-/A/g' file

Замените file на "$1" в вашем коде.

ОБНОВЛЕНИЕ

Вот перевод кодировка / декодирование Python функция опубликовано Матиасом ниже:

#!/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 "- .... .. ...   .. ...   ..-. .. -. .")"

См. Bash демонстрация онлайн .

0 голосов
/ 06 февраля 2020

Простой ответ в двигателях RE, поддерживающих упреждающий просмотр и упускание, состоит в том, чтобы рассматривать пробелы как триггеры упреждения и обратного просмотра, но sed не поддерживает это.

Еще один вариант, который избавляет от необходимости заказывать буквы - это вводить дополнительные символы, чтобы помочь вам пометить каждую букву Скажем, мы вставляем = округляем каждый пробел, затем мы можем заменить последовательности с разделителями в любом порядке и, наконец, избавиться от разделителей:

echo  .- .-.|sed -e 's/^\(.*\)$/=\1=/;s/ /= =/g' -e 's/=\.-\.=/=R=/g;s/=\.-=/=A=/g' -e 's/= =//g;s/^=//;s/=$//'

Если у вас есть правила, которым нужно сохранять несколько пробелов, то это может быть размещение.

...