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


9

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

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

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

私は試した:

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



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

編集 キャラクターの詳細:

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

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


それはどのように機能sed -i "s/\x91/'/g"fileませんか?
ステファンChazelas

回答:


3

あなたは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は引数スタックからこれをポップし、(私がところで、1つのライナーよりも短いスクリプトを微調整しやすいとして仕事を見つける)の入力に使用するファイルパスとしてそれを取ります。これはメモリに蓄積され(ファイルが大規模でない限り問題ありません)、perl -i元のファイルの名前を変更して、インプレース編集の競合状態を回避します(を参照perldoc perlrun)。

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

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

それは機能しません、疑問符は残ります...
ジャスミン

チェックインしてhexdump -C実際に何があるか確認しましたか?
goldilocks 2014

3

それが実際に文字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文字は1バイトで、ASCII文字の場合のみ(値0〜0x7F)。他の文字は、値が2バイト以上で表されます。0x7F。したがって、その0x91周りに0x7Fを超えるバイトがないバイトは、utf-8ファイルでは見つかりません。

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

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 {} +

それは機能しません、疑問符は残ります...
ジャスミン

@jasminesでは、それはではありませんU+0091。の出力をLC_ALL=C sed -n l < file質問に追加してください。
ステファンChazelas

221

は単一のファイルではないため、変換できません...バッチで再帰的に検索して置換する必要があります。
ジャスミン14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.