搜索与特殊字符类似的字符

时间:2016-04-10 18:24:32

标签: perl unix search grep special-characters

我有几个旧的文本数据文件是使用旧的DOS时代的文字处理器在90年代生成的。由于当时存在的限制,在数据输入过程中有许多条目被“简化”。

例如,“Náufragos”一词输入为“Naufragos”。

现在,当在所述数据文件中搜索“Náufragos”时,我使用grep查找“Náufragos”并且搜索结果为空(它应该是),但我确实需要搜索来查找并输出“Naufragos”。

我已经梳理了grep文档并广泛使用Google搜索,但是空白了。

任何解决方案都需要处理涉及拉丁字母表中基于的大多数(如果不是全部)字符“变体”的案例(即,中文中没有中文,西里尔文,日文等)旧数据文件)。

是否有grep或者perl选项才能执行此操作?也许是这样的事情:

grep -<magic option> Náufragos file.txt

2 个答案:

答案 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;

但是,更好的脚本会匹配旧/新名称,因为很容易忽略转换的文件。是否要忽视案例也是值得考虑的事情。