我有两个文本文件File_A和File_B。 File_A包含以下项
a अ
aa आ
b a ब
bh a भ
c a च
ch a छ
d a द
dh a ध
dx a ड
dxh a ढ
g a ग
gh a घ
h a ह
j a ज
jh a झ
k a क
kh a ख
l a ल
m a म
n a न
nx a ण
p a प
ph a फ
r a र
s a स
sh a श
t a त
th a थ
tx a ट
txh a ठ
w a व
y a य
z a ज़
b ब
bh भ
c च
ch छ
d द
dh ध
dx ड
dxh ढ
ee े
ei ै
g ग
gh घ
h ह
i ि
ii ी
j ज
jh झ
k क
kh ख
l ल
m म
n न
nx ण
o ो
ou ौ
p प
ph फ
r र
s स
sh श
t त
th थ
tx ट
txh ठ
u ु
uu ू
w व
y य
z ज़
b aa बा
bh aa भा
c aa चा
ch aa छा
d aa दा
dh aa धा
dx aa डा
dxh aa ढा
g aa गा
gh aa घा
h aa हा
j aa जा
jh aa झा
k aa का
kh aa खा
l aa ला
m aa मा
n aa ना
nx aa णा
p aa पा
ph aa फा
r aa रा
s aa सा
sh aa शा
t aa ता
th aa था
tx aa टा
txh aa ठा
w aa वा
y aa या
z aa ज़ा
[如果您在上面的文件中看到详细信息,例如第一行“ aअ”,则在罗马和devnagari之间的每一行都有一个制表符。间接地,我试图用after标签替换before标签。我正在尝试替换File_B中包含以下内容的音素。
dx o n aa l d s
我尝试使用shell脚本,但输出错误。这是代码。
#!/bin/bash
while read p q
do
echo "P is : " $p
echo "Q is : " $q
echo "-----------------"
# sleep 3
sed -i "s/\<$p\>/$q/g" $2
done < $1
得到的输出是:
a ड ो a न आ a ल a द a स
我期望是:
ड ो ना ल द स
都接受Python或Shell。
文件“ awk_script”:
#! /usr/bin/env awk
BEGIN {
counter = 0
}
{
if (FNR == NR) {
# Store key val pairs from first file
key[counter] = $1
value[counter] = $2
counter++
} else {
# Replace stored key val pairs in second file
for (i = 0 ; i < counter ; i++) {
gsub(key[i], value[i], $0)
}
print
}
}
文件“ bash_script”
#! /usr/bin/env bash
file1='File_A'
file2='File_B'
temp_file1="$( mktemp "/tmp/${file1}-XXXXX" )"
awk_script_file_name='awk_script'
#
# Create a temp file which is reverse
# sorted based on length of the keys
# and pass that temp file to awk script
#
awk -F'\t' -v OFS='~' '{
print $1, $2, length($1)
}' "${file1}" |
sort -r -n -t '~' -k3 > "${temp_file1}"
awk \
-F'~' \
-f "${awk_script_file_name}" \
"${temp_file1}" \
"${file2}"
rm "${temp_file1}"
PS:此脚本使用命令的BSD变体,可能必须进行调整以适应GNU变体。
基于Perl的解决方案:
#!/usr/bin/env perl
use warnings;
use strict;
use autodie;
use feature qw/say/;
use open qw/:std :locale/;
my @mappings;
open my $file, "<:encoding(UTF-8)", $ARGV[0];
while (my $line = <$file>) {
chomp $line;
push @mappings, [ split /\t/, $line ];
}
close $file;
@mappings = sort { my $x = length $b->[0] <=> length $a->[0];
$x != 0 ? $x : $a->[0] cmp $b->[0] } @mappings;
# Precompile the regular expressions
@mappings = map { [ qr/\b$_->[0]\b/, $_->[1] ] } @mappings;
open $file, "<:encoding(UTF-8)", $ARGV[1];
while (my $line = <$file>) {
my $output;
chomp $line;
for my $pair (@mappings) {
my ($roman, $devnagari) = @$pair;
$line =~ s/$roman/$devnagari/g;
}
say $line;
}
File_A和File_B分别在命令行上传递:
$ perl convert.pl file_a.txt file_b.txt
ड ो ना ल द स
简单的粗略的全局替换方法不起作用,因为,例如,a
是一个独立的音素,并且是许多较长音素的一部分。如果对音素列表进行排序,以便首先检查最长的令牌(因此,无论c a
在c
之前都匹配,无论它们在File_A中的出现顺序如何),使用该方法都将变得更加合理。您也可以尝试从文本开头匹配最长的音素,将其弹出,然后重复进行直到所有输入字符串都用完。