我们假设我有一个名为m1.txt
的文件,其内容(- . ... - / -. --- / .----
)我想从莫尔斯解码为文本。这是我写的:
sed -i 's/.- /A/g' m1.txt
sed -i 's/-... /B/g' m1.txt
sed -i 's/-.-. /C/g' m1.txt
等等,包括数字,以及稍后:
sed -i 's:/ : :g' m1.txt
cat m1.txt
以清除分隔斜杠并输出消息。
预期输出为TEST NO 1
,但程序输出D...AE-ED.--A
,忽略任何空格并返回错误信息。我做错了什么?
答案 0 :(得分:4)
两件事:
.
,因为它会匹配任何字符.
(E)将匹配单个点,它也会匹配(N)-.
的结尾,除非您按正确的顺序考虑它们或保留分隔符(左右两侧)。(1)显然要解决,只需逃避.
。
对于(2),我们可以首先将行的开头和结尾映射到空格(这样我们左右一致地使用分隔符,然后我们在输出上保留分隔符(以避免交互)。然后,在第二个到最后一行,清理空格。然后,在最后一行中,将斜杠映射到单词间隔空格,这是您输出中唯一需要的空格。
我没有为你做整个字母表,只是足以让你看到这个想法。
这是一个有效的解决方案:
$ cat m1.txt
- . ... - / -. --- / .----
$ cat morse.sed
s/^/ /
s/$/ /
s/ - / T /g
s/ \. / E /g
s/ \.\.\. / S /g
s/ -\.\ / N /g
s/ --- / O /g
s/ \.---- / 1 /g
s/[ ]\+//g
s:/: :g
$ cat m1.txt | sed -f morse.sed
TEST NO 1
注意:此答案已修订,因为我没有意识到(
和)
不是输入的一部分。另外,@ Bach Lien想要将锚点映射到第一行中的空格是一个很好的想法,它使事情变得更加清晰,所以我已经将这个想法融入其中。
答案 1 :(得分:3)
莫尔斯表(莫尔斯到字母映射):
$ cat morse-table.txt
## this is table of char-to-morse-code mapping
## taken from https://en.wikipedia.org/wiki/Morse_code
## dated: 2018 01 23
## characters
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 --..
## numbers
1 .----
2 ..---
3 ...--
4 ....-
5 .....
6 -....
7 --...
8 ---..
9 ----.
0 -----
## special symbols
## in fact, there is no
## such symbols in traditional morse codes
## this part is fake, just for testing
. .......
\ -------
/ -.-.-.-
? --.--.-
[ .--.--.
] --..--.
将莫尔斯桌转换为sed
脚本的程序:
$ cat make-m2t.sh
#!/bin/bash
t=morse-table.txt # morse table
s=m2t # sed script
s1=' # s1 = pre-processing
s:\s+: :g # space-gap to TWO space-chars
s:^: : # add a space at line beginning
s:$: : # add a space at line end
s:/: \n :g # change all slash to " \n "
'
s2=' # s2 = morse-table to sed-script
s:\s+: :g # space-gap to space-char
s:##.*$:: # remove all comments
s:^ *:: # remove all leading spaces
s: *$:: # remove all trailing spaces
/^[^ ] [\.-]+$/!d # ignore all invalid lines
s:\.:\\.:g # add back-slash for dot (escape for dot)
s:^\\\. :\. : # but not for the char-dot
s:^\\ :\\\\ : # add b-slash for b-slash (escape for b-slash)
s:^\/ :\\\/ : # add b-slash for slash (escape for slash)
s:^([^ ]+) +([^ ]+).*$:s/ \2 / \1 /g: # morse-map to sed-subsitution
'
s3=' # s3 = post-processing
s: ::g # remove all spaces
s:\n: :g # convert \n to space
'
# now, make the sed script
echo '#!/usr/bin/sed -Ef' >"$s" # shebang
sed -E 's:\s*#.*$::' <<<"$s1" >>"$s" # remove comments from s1
sed -E "$s2" "$t" >>"$s" # convert morse to chars
sed -E 's:\s*#.*$::' <<<"$s3" >>"$s" # remove comments from s3
sed -i -E '/^\s*$/d' "$s" # remove all blank lines
chmod +x "$s" # make it executable
测试:
$ ./make-m2t.sh
$ echo '- . ... -/-. ---/.----' | ./m2t
TEST NO 1
$ echo '.--.--. .... . .-.. .-.. --- --..--./....... --.--.-' | ./m2t
[HELLO] .?
$ cat m1.txt
- . ... - / -. --- / .----
$ ./m2t m1.txt
TEST NO 1
$ cat m2t
#!/usr/bin/sed -Ef
s:\s+: :g
s:^: :
s:$: :
s:/: \n :g
s/ \.- / A /g
s/ -\.\.\. / B /g
s/ -\.-\. / C /g
s/ -\.\. / D /g
s/ \. / E /g
s/ \.\.-\. / F /g
s/ --\. / G /g
s/ \.\.\.\. / H /g
s/ \.\. / I /g
s/ \.--- / J /g
s/ -\.- / K /g
s/ \.-\.\. / L /g
s/ -- / M /g
s/ -\. / N /g
s/ --- / O /g
s/ \.--\. / P /g
s/ --\.- / Q /g
s/ \.-\. / R /g
s/ \.\.\. / S /g
s/ - / T /g
s/ \.\.- / U /g
s/ \.\.\.- / V /g
s/ \.-- / W /g
s/ -\.\.- / X /g
s/ -\.-- / Y /g
s/ --\.\. / Z /g
s/ \.---- / 1 /g
s/ \.\.--- / 2 /g
s/ \.\.\.-- / 3 /g
s/ \.\.\.\.- / 4 /g
s/ \.\.\.\.\. / 5 /g
s/ -\.\.\.\. / 6 /g
s/ --\.\.\. / 7 /g
s/ ---\.\. / 8 /g
s/ ----\. / 9 /g
s/ ----- / 0 /g
s/ \.\.\.\.\.\.\. / . /g
s/ ------- / \\ /g
s/ -\.-\.-\.- / \/ /g
s/ --\.--\.- / ? /g
s/ \.--\.--\. / [ /g
s/ --\.\.--\. / ] /g
s: ::g
s:\n: :g
注意:强>
bash
程序会生成sed
脚本以将莫尔斯代码转换为文本sed
脚本基于@JawguyChooser的解决方案。' '
作为&#34;分隔符&#34;莫尔斯块,所以,当预处理我们必须将所有空间间隔转换为两个空格字符;否则会出现'HELLO'
(双L
)