使用bash将字符串转换为另一种语言

使用bash将字符串转换为另一种语言,bash,translate,letters,latin,Bash,Translate,Letters,Latin,我创建了一个脚本,可以用拉丁语和希腊语字符获取人们的名字和姓氏。我的挑战是将所有希腊字符翻译成拉丁字符,以便创建更多可能的Facebook链接到他们的个人资料,但只使用bash,而不使用python、ruby等 我创建了一个类似哈希表的文件,它看起来像这样(请看下面),并遵循一个简单的规则。。。每个记录用逗号分隔,1st字段表示字母的附加表达方式的数量,2nd字段表示我要查找的希腊字母和下一个字母(3rd和/或4th)表示希腊字母是如何用拉丁语表达的 0,Α,A 0,Β,B 0,Γ,G 0,Δ,

我创建了一个脚本,可以用拉丁语和希腊语字符获取人们的名字和姓氏。我的挑战是将所有希腊字符翻译成拉丁字符,以便创建更多可能的Facebook链接到他们的个人资料,但只使用bash,而不使用python、ruby等

我创建了一个类似哈希表的文件,它看起来像这样(请看下面),并遵循一个简单的规则。。。每个记录用逗号分隔,1st字段表示字母的附加表达方式的数量,2nd字段表示我要查找的希腊字母和下一个字母(3rd和/或4th)表示希腊字母是如何用拉丁语表达的

0,Α,A
0,Β,B
0,Γ,G
0,Δ,D
0,Ε,E
0,Ζ,Z
0,Η,I
0,Θ,TH
0,Ι,I
0,Κ,K
0,Λ,L
0,Μ,M
0,Ν,N
1,Ξ,X,KS
0,Ο,O
0,Π,P
0,Ρ,R
0,Σ,S
0,Τ,T
1,Υ,Y,U
1,Φ,F,PH
1,Χ,CH,H
0,Ψ,PS
1,Ω,O,W
现在,经过几个小时的研究,我还没有找到任何完全符合我需要的东西。 我尝试过的方法是向函数传递一个字符串,然后函数从它的哈希表中加载它必须翻译的每个字母,并将其输出到一个名为data.tr的文件中,但没有成功

函数greek2latin() { #用法:希腊语 而读散列 做 希腊文=$(echo$hash | cut-d','-f2) latin0=$(echo$hashed | cut-d','-f3) echo$1 | tr'$greek'$latin0'>“$PWD”/data/data.tr #请注意,“1”被读取为字符串,因此比较为1 #也许我以后需要改变 如果[$(echo“$hashed”| cut-d','-f1)=“1”] 然后 拉丁语1=$(echo$hashed | cut-d','-f4) echo$1 | tr'$greek'$latin1'>“$PWD”/data/data.tr fi 完成<“$PWD”/data/hash.synonyms/greek2latin } 有人能告诉我为什么它不能按预期工作吗?我非常感谢你的帮助

谢谢!:)

(0)初步来说,在语言a中取一个单词,并将每个字母(有时是字母对)改成字母(或字母对),在语言B中发音(大致相同),但在语言B中不改成单词,这不是翻译,而是音译。此外,您的“表”文件不是散列文件或散列文件;它只是一个包含所需翻译的文件

(1) 您的脚本不会更改任何内容,因为shell变量不会在单引号内展开;事实上,单引号中没有赋予任何特殊含义,具体如下:

将字符括在单引号(“”)中会保留引号中每个字符的文字值。单引号不能出现在单引号之间,即使前面有反斜杠

因此,您告诉
tr
$
替换
$
,用
l
替换
g
,用
a
替换
r
,用
i
替换
e
,用
n
替换
k
。由于您的输入可能不包含任何
$GREK
项,因此这不会起任何作用

(2A)如果您使用双引号来解决此问题,双引号确实展开了
$var
(以及此处不相关的一些其他内容),它在某些情况下仍然不起作用,因为
tr
会逐字符替换。因此,如果你用第一个参数XI(一个字符,见下一个)和第二个参数<代码> KS > /Cube >(两个字符),它将把任何(和所有)席席翻译成<代码> K<代码>,并且永远不要使用<代码> s <代码>。p>

将单个字符转换为可能不止一个字符的字符串,请考虑<代码> SED或类似“代码> AWK < /COD>或<代码> Perl < /C>。或者,因为您想要“仅bash”,所以可以使用bash自己的字符串替换,如

${1//$greek/$latin}

(2B)另一个可能的问题是,许多(但肯定不是所有)带有GNU外壳
bash
的系统也有GNU coreutils实现
tr
,而不支持多字节字符,即UTF-8。如今,大多数“多语言”(更准确地说是非英语/非ASCII)材料都采用UTF-8编码。但是,如果您的输入(脚本和数据)在8859-7中,或者可以转换为8859-7,则GNU
tr
可以使用,但多字符情况除外

(3) 您不需要多个
cut
进程来解析输入行;shell
read
可以做到:

while IFS=, read flag greek latin0 latin1; do
  echo "${1//$greek/$latin0}" >>output
  if [ "$flag" == "1" ]; then echo "${1//$greek/$latin1}" >>output; fi
done <translationsfile
当IFS=时,读取标志希腊拉丁语拉丁语1;做
echo“${1/$greek/$latin0}”>>输出
如果[“$flag”==“1”];然后回显“${1/$greek/$latin1}”>>输出;fi
初步完成(0)在语言a中取一个单词,并将每个字母(有时是字母对)改为字母(或字母对),在语言B中发音(大致相同),但在语言B中不改为单词,这不是翻译,而是音译。此外,您的“表”文件不是散列文件或散列文件;它只是一个包含所需翻译的文件

(1) 您的脚本不会更改任何内容,因为shell变量不会在单引号内展开;事实上,单引号中没有赋予任何特殊含义,具体如下:

将字符括在单引号(“”)中会保留引号中每个字符的文字值。单引号不能出现在单引号之间,即使前面有反斜杠

因此,您告诉
tr
$
替换
$
,用
l
替换
g
,用
a
替换
r
,用
i
替换
e
,用
n
替换
k
。由于您的输入可能不包含任何
$GREK
项,因此这不会起任何作用

(2A)如果您使用双引号来解决此问题,双引号确实展开了
$var
(以及其他一些与此不相关的内容),则在某些情况下仍然不起作用,因为
tr
会逐个字符替换while IFS=, read flag greek latin0 latin1; do echo "${1//$greek/$latin0}" >>output if [ "$flag" == "1" ]; then echo "${1//$greek/$latin1}" >>output; fi done <translationsfile