web-dev-qa-db-ja.com

テキストファイルから不明なUnicode文字を削除-sed、その他のbash / Shellメソッド

同じ名前のいくつかのファイルで、不明な文字のすべての出現を検索して置き換える必要があります。

そのようなファイルをviで開いて、その文字の<91>コードを読みました。それらをnanoで開くと、ダイヤモンド(黒のランブル)の「疑問符」を読みました。

このような不明な文字を引用符( ')に置き換えたいと思います。運が悪いのにいろいろな方法を試しています。

私は試した:

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



find ./ -name filename.txt -exec sed -i "s/\x91/'/g" {} \;

[〜#〜] edit [〜#〜]キャラクターの詳細:

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

さらに必要な場合は、質問してください!

9
jasmines

hexdump -Cを使用して見て、その周りのバイトを見つける必要があります。 UTF-8を想定すると、vi<91>(10進数145、テキストでは意味のないユニコードポイント)として表示されるものは、2バイト、0xc2および0x91になります。

それはあなたの置換がまったく機能しなかったことを意味します、しかしあなたがしたことが単に0x91を0x27で置き換えたなら、あなたはUTF-8を無効にしたでしょう(2バイトシーケンスの2番目のバイトは常にハイビットセットを持っています、すなわち> = 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;  

$ARGV[0]が参照されているときに<>が存在する場合、Perlはこれを引数スタックからポップし、それを入力に使用するファイルパスとして取得します(短いスクリプトを調整して、複数のライナー、BTWで操作する方が簡単だと思います)。 。これはメモリに蓄積されますが(ファイルが大規模でない限り問題ありません)、Perl -iは元のファイルの名前を変更して、インプレース編集の競合状態を回避します(perldoc perlrunを参照)。

だからあなたはそれを使うことができます:

  find . -name "*.txt" -exec whatever.pl {} +
3
goldilocks

それが実際に文字U + 0091(UTF-8エンコーディングでは0xc2 0x91)であり、バイト0x91ではない場合、次のようになります。

PERLIO=:utf8 Perl -pi -e "s/\N{U+0091}/'/g" file

'に変換します。

GNU sed

sed -i "s/\xc2\x91/'/" file

編集:

ただし、あなたの場合、ファイルはUTF-8ではありません。 UTF-8文字は、ASCII文字(値0〜0x7Fの場合)の場合のみ、1バイトです。他の文字は、値が0x7Fより大きい2バイト以上で表されます。そのため、その周りに0x7Fを超えるバイトがない0x91バイトは、utf-8ファイルでは見つかりません。

可能性が高いのは、ファイルがシングルバイト文字セットであり、おそらくMicrosoftの windows-1252 のようなものです。

Windows-1252では、0x91が左の一重引用符です。同等のUnicodeはU + 2018で、UTF-8では0xe2 0x80 0x98と記述されています。

ファイルをUTF-8に変換する場合は、おそらく専用のツールを使用することをお勧めします。お気に入り:

recode windows-1252..utf8 < file

または:

iconv -f windows-1252 -t utf-8 < file

または、filename.txtごとに実行する場合:

find . -type f -name filename.txt -exec sh -Cc '
  for file do
    mv "$file" "$file~" &&
      iconv -f windows-1252 -t utf-8 < "$file~" > "$file"
  done' sh {} +
3