我正在使用的一些代码有很多用日语编写的注释,我正在努力将它们翻译成英语。有没有某种方法可以“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 用于打印行名称旁边的行号
\x80
to\xff
是“非 ASCII”字符
将 LC_CTYPE 环境变量更改为 iso-8859-1 使 grep 逐字节读取我的字段,并让我检测任何“扩展 ascii”字节作为可能的日语字符。如果我使用 UTF-8 的默认系统编码,则 grep 退出时出现“输入中的无效 UTF-8 字节序列”错误。