如何将文件中的每个非 ASCII UTF-8 字符替换为零

如何将文件中的每个非 ASCII UTF-8 字符替换为零

源是源仅是 UTF-8...需要将除 ASCII 字符集(代码点 U+0000 到 U+007F)之外的每个 UTF-8 字符替换为零,如下行所示,

This is line 001122��33
this is second line ¿½1122ï

这应该被替换为

This is line 0011220033
this is second line 00112200

这是我用来手动执行的格式。

grep -P "[^\x00-\x7F]" filename

答案1

Perl 来救援!

perl -C -pe 's/[\x{80}-\x{ffffffff}]/0/g'
  • -p逐行读取输入,运行每行代码并在处理后打印它
  • -C打开 UTF-8

答案2

在兼容 POSIX 的系统上以及使用 UTF-8 字符集的语言环境中,您可以执行以下操作:

tr -c '\0-\177' '[0*]' < file

但请注意,至少 GNU 实现tr在这方面不兼容,因为它还不支持多字节字符。

在 GNU 系统上,您可以使用 GNUawk来实现这一点,但在最近的版本中,范围是基于代码点的:

LC_ALL=C.UTF-8 gawk '{gsub(/[^\0-\177]/, "0"); printf "%s", $0 RT}' < file

答案3

假设您是 POSIX 用户,因为您没有提供其他信息。

这应该适用于每个 POSIX 环境,因为 ecerything 是通过 POSIX shell 的 POSIX 实用程序完成的:

cat filename |
# each character to octal
od -A n -v -t o1 |
# remove blanks and make each line be '/^[0-7]..$/'
fold -sw3 | grep -v ' ' |
# if it is UTF-8 specific, then let it be 060: stands for "0"
# OBTW I referred RFC3629
# NOTE it does not care for broken characters.
sed '
  /^36/{$!N;$!N;$!N;s/^36..2...2...2../060/;}
  /^3[45]/{$!N;$!N;s/^3...2...2../060/;}
  /^3[0-3]/{$!N;s/^....2../060/;}' |
# insert \\ for xargs printf
sed 's/^/\\\\/' |
# buffering
# variable max is as in limits.h in POSIX, I think.
awk '
BEGIN{buffer="";max=4096-9;}
{
  if(length(buffer $0)<max)
    buffer=buffer $0;
  else{
    print buffer;
    buffer="";}}
END{
  if(buffer!="")
    print buffer;}' |
# finally
# NOTE that I have never tested if this would work if
# filename were empty, on every POSIX environment
# I have tested it only on GNU/Linux.
xargs -Ix printf x

如果您无法安装任何其他方便的东西,您也不用惊慌;你应该尝试使用你身上的工具。

相关内容