有没有办法 grep 文件夹并显示包含非 ascii 字符的所有行?

有没有办法 grep 文件夹并显示包含非 ascii 字符的所有行?

我正在使用的一些代码有很多用日语编写的注释,我正在努力将它们翻译成英语。有没有某种方法可以“grep”包含日语字符或至少任何非 ASCII 字符的所有行?

答案1

查找非 ASCII 字符很简单:设置仅 ASCII 字符有效的区域设置,搜索无效字符。

LC_CTYPE=C grep '[^[:print:]]' myfile

如果你想搜索日语字符,那就有点复杂了。使用 grep,您需要确保您的LC_CTYPE区域设置与文件的编码相匹配。LC_COLLATE如果您想使用字符范围表达式,您还需要确保您的设置设置为日语。例如,在 Linux 上(我通过查看 部分确定了被视为日语的第一个和最后一个字符LC_COLLATE/usr/share/i18n/locales/ja_JP

LC_CTYPE=ja_JP.UTF-8 LC_COLLATE=ja_JP.UTF-8 egrep '[。-龥]' myfile

或者如果您想在脚本中坚持使用 ASCII

LC_CTYPE=ja_JP.UTF-8 LC_COLLATE=ja_JP.UTF-8 egrep $'[\uff61-\u9fa5]' myfile

这包括一些也在英语中使用的标点符号,例如×

Perl 具有对字符进行分类的内置功能。您可以使用\p字符类匹配基于的字符统一码属性。通过命令行开关-CSD告诉 Perl 所有内容都是采用 UTF-8 编码的 Unicode。

perl -CSD -ne 'print if /\p{Hiragana}|\p{Katakana}/' myfile

如果您的文件不是以 UTF-8 编码,您必须调用binmode明确地告诉 Perl 它们的编码。这也太先进了吧全局区域设置对我来说用法。或者你也可以首先将该行重新编码为 UTF-8

或者,在 Perl 中,您可以使用数字字符范围。例如,要搜索平假名和片假名 Unicode 块中的字符:

perl -CSD -ne 'print if /[\x{3040}-\x{30ff}]/' a

答案2

尝试这个:

grep '[^[:print:][:space:]]'

(根据您的区域设置,也许您必须在其前面加上LANG=C。)

答案3

如果您不介意使用 perl,它以类的形式提供更广泛的 Unicode 支持,例如{Katakana}{Hiragana}我认为即使在提供一些 PCRE 支持的 grep 版本中,目前也无法使用这些类。然而它似乎确实需要显式的 UTF-8 解码,例如

perl -MEncode -ne 'print if decode("UTF-8",$_) =~ /\p{Hiragana}/' somefile

要遍历像 grep 的 -R 这样的目录,您可以使用find类似的命令

find -type f -exec perl -MEncode -ne 'print if decode("UTF-8",$_) =~ /\p{Hiragana}/' {} \;

或模仿递归 grep 的默认filename:match标记输出格式,

find -type f -exec perl -MEncode -lne 'printf "%s:%s\n",$ARGV,$_ if decode("UTF-8",$_) =~ /\p{Hiragana}/' {} \;

答案4

我的文件采用 iso-8859-1 编码,因此尝试读取我的默认语言环境 (utf-8) 中的输入的任何内容都无法识别日语字符。最后我设法用以下命令解决了我的问题:

env LC_CTYPE=iso-8859-1  grep -nP '[\x80-\xff]' ./*

-P 允许字符范围使用 Perllike 语法。
-n 用于打印行名称旁边的行号

\x80to\xff是“非 ASCII”字符

将 LC_CTYPE 环境变量更改为 iso-8859-1 使 grep 逐字节读取我的字段,并让我检测任何“扩展 ascii”字节作为可能的日语字符。如果我使用 UTF-8 的默认系统编码,则 grep 退出时出现“输入中的无效 UTF-8 字节序列”错误。

相关内容