从文本文件中删除未知的 unicode 字符 - sed、其他 bash/shell 方法

jas*_*nes 9 sed perl wildcards replace file-search

我需要在某些具有相同名称的文件中搜索并替换所有出现的未知字符。

使用 vi 打开此类文件,我读取了该字符的 <91> 代码。用nano打开它们,我读到一个菱形(黑色隆隆声)上的“问号”。

我想用引号 (') 替换这种未知字符。我尝试了很多方法但没有运气。

我试过:

find ./ -name filename.txt -exec perl -i~ -pe "s/\x91/'/" {} \;



find ./ -name filename.txt -exec sed -i "s/\x91/'/g" {} \;
Run Code Online (Sandbox Code Playgroud)

编辑 有关角色的更多信息:

Hexadecimal: 91 68 74 74
Decimal: 145 104 116 116
Octal: 221 150 164 164
Binary: 10010001 01101000 01110100 01110100

LC_ALL=C sed -n l < file

\221
Run Code Online (Sandbox Code Playgroud)

如果您需要更多,请询问!

gol*_*cks 3

您应该看看使用hexdump -C并找到它周围的字节。假设UTF-8,vi显示为<91>(十进制145,文本中无意义的unicode点)将是两个字节,0xc2和0x91。

这意味着你的替换根本不起作用,但如果你所做的只是用 0x27 替换 0x91,你就会使 UTF-8 无效(双字节序列的第二个字节总是设置高位,即>= 0x80)。这可能会使您的分析复杂化,尽管vi随后应将其显示为?'

也就是说,我测试了这个并且它有效:

#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);

my $data = "";
my $file = $ARGV[0];

while (<>) {
    s/\xc2\x91/'/g;
    $data .= $_;
}

open my $out, '>', $file || die "Could not write $file.";
print $out $data;
close $out;  
Run Code Online (Sandbox Code Playgroud)

如果引用$ARGV[0]时存在<>,perl 会将其从参数堆栈中弹出,并将其作为用于输入的文件路径(顺便说一句,我发现短脚本比一个衬垫更容易调整和使用)。这会在内存中累积(只要文件不是很大就可以),而重perl -i命名原始文件以避免就地编辑竞争条件(请参阅 参考资料perldoc perlrun)。

所以你可以使用它:

  find . -name "*.txt" -exec whatever.pl {} +
Run Code Online (Sandbox Code Playgroud)