ファイルでASCII以外のUTF-8文字をすべて0に置き換える方法

ファイルでASCII以外のUTF-8文字をすべて0に置き換える方法

ソースはUTF-8のみです... ASCII文字セット(コードポイントU + 0000〜U + 007F)を除くすべてのUTF-8文字は、次の行に示すように0に置き換える必要があります。

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入力を1行ずつ読み、各コード行を実行し、処理後に印刷します。
  • -CUTF-8 オン

答え2

UTF-8文字セットを使用するPOSIX準拠のシステムおよびロケールでは、次のことができます。

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

ただし、少なくともGNU実装はtrまだマルチバイト文字をサポートしていないため、これに関して互換性はありません。

GNUシステムではawkGNUを使用してこれを実行できますが、最新バージョンではスコープはコードポイントベースです。

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

答え3

他の情報を提供していないため、お客様はPOSIXユーザーとみなされます。

すべてのPOSIX環境で動作する必要があります。なぜなら、すべての操作はPOSIXシェルの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

他の便利なツールをインストールできない場合でも、パニックにならないでください。持っているツールを試してください。

関連情報