将文本文件中的单词替换为用于音素的音素

问题描述 投票:0回答:2

我有两个文本文件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。

bash
2个回答
1
投票

文件“ 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变体。


0
投票

基于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 ac之前都匹配,无论它们在File_A中的出现顺序如何),使用该方法都将变得更加合理。您也可以尝试从文本开头匹配最长的音素,将其弹出,然后重复进行直到所有输入字符串都用完。

© www.soinside.com 2019 - 2024. All rights reserved.