我有几个旧的文本数据文件是使用旧的DOS时代的文字处理器在90年代生成的。由于当时存在的限制,在数据输入过程中有许多条目被“简化”。
例如,“Náufragos”一词输入为“Naufragos”。
现在,当在所述数据文件中搜索“Náufragos”时,我使用grep查找“Náufragos”并且搜索结果为空(它应该是),但我确实需要搜索来查找并输出“Naufragos”。
我已经梳理了grep文档并广泛使用Google搜索,但是空白了。
任何解决方案都需要处理涉及拉丁字母表中基于的大多数(如果不是全部)字符“变体”的案例(即,中文中没有中文,西里尔文,日文等)旧数据文件)。
是否有grep或者perl选项才能执行此操作?也许是这样的事情:
grep -<magic option> Náufragos file.txt
答案 0 :(得分:1)
要忽略变音符号,您可以使用级别1的Unicode归类算法进行搜索。
#!/usr/bin/perl
use strict;
use warnings;
use Unicode::Collate;
my $collator=Unicode::Collate->new(level => 1, normalization => undef);
while (<>) {
print if $collator->match($_, "Naufragos")
}
将此脚本命名为ucagrep.pl
:
$ echo -e "Náufragos\nNaufragos\nÑaufragos" | perl -CS ucagrep.pl
Náufragos
Naufragos
Ñaufragos
呃。我们最好指定语言环境:
#!/usr/bin/perl
use strict;
use warnings;
use Unicode::Collate::Locale;
my $collator=Unicode::Collate::Locale->new(locale => "es", level => 1, normalization => undef);
while (<>) {
print if $collator->match($_, "Naufragos")
}
测试它:
$ echo -e "Náufragos\nNaufragos\nÑaufragos" | perl -CS ucagrep.pl
Náufragos
Naufragos
好多了。
答案 1 :(得分:0)
您总是可以使用字符范围进行grep,例如,
grep -i 'N[aá]ufragos' *
匹配名称的拼写,如果这是令人讨厌的话, Text::Unidecode
中讨论的使用How to convert letters with accents, umlauts, etc to their ASCII counterparts in Perl?的脚本可以生成范围表达式(因为您可能只处理ISO-8859-1中具有变音符号的几十个字符)。
Text::Unidecode
的一个缺点是它不太可能预先安装在系统上(我看到例如Debian中没有包)。您可以直接从CPAN获取,例如,使用cpanminus
。
这是一个简单的例子,只是搜索旧名称(cpanminus将包放在非标准位置):
#!/usr/bin/perl -w
use strict;
use lib '/usr/local/lib/perl';
use Text::Unidecode;
my @args = unidecode(@ARGV);
for my $n ( 0 .. $#args ) {
my $name = $args[$n];
printf "** grep %s ->%s\n", $ARGV[$n], $args[$n];
system("grep -r \"$name\" .");
}
1;
但是,更好的脚本会匹配旧/新名称,因为很容易忽略转换的文件。是否要忽视案例也是值得考虑的事情。