web-dev-qa-db-ja.com

UTF-8ロケールでUTF-16LEファイルで正規表現検索を実行するにはどうすればよいですか?

編集:コメントウォーレン・ヤングが行ったため、私は1つの非常に関連性のある点について明確ではなかったことに気づきました。私の検索文字列はすでにUTF-16LEの順序になっています(UTF-16BEであるUnicodeコードポイントの順序ではありません)ので、Unicodeの問題はやや議論の余地があります。

おそらく私の問題は、2バイトのグループでバイト(charではなく)をgrepする方法の問題です。そのため、UTF-16LE \x09\x0AはTAB、改行としてではなく、たまたまUTF-16LE である2バイトとして扱われますか? ...注:UTF-16サロゲートペアについて心配する必要はないので、2バイトのブロックで問題ありません。

この3文字の文字列ऊपरのサンプルパターンは次のとおりです。

  • \x09\x0A\x09\x2A\x09\x30

    ただし、文字列はファイルに含まれていますが、何も返されません。

(これが元の投稿です)
\x00\x01\x...etc形式のパターンでUTF-16LEファイルを検索すると、いくつかの値で問題が発生しました。私はsedを使用しています(そしてgrepで実験しました)が、UTF-8ロケールにあるため、いくつかのUTF-16LE値をASCII文字として認識します。私はUTF-16の使用に縛られているので、UTF-8に再コーディングすることはできません。

例えば。このテキストでは、(UNICODE 090A)は単一の文字ですが、は2つのASCII chars\x09\x0Aとして認識されます。

grepには-Pパターンを検索できる\x00\x...(Perl)オプションがありますが、同じASCIIの解釈が得られます。

grep -Pを使用してUTF-16モードで検索する方法はありますか、それとももっと良い方法は、Perlまたはその他のスクリプトです。

grepはそのコンパクトさのために最も魅力的であるように思われますが、仕事を成し遂げるものは何でもその好みを無効にします。

PS;私のの例ではリテラル文字列を使用していますが、実際の使用法では正規表現スタイルの検索が必要です。したがって、 このPerlの例 は、ファイルをUTF-16として処理しますが、私が求めているものではありません...ファイルを開いたり閉じたりする必要はありません... I Perlには、正規表現検索などの基本的なもののためのよりコンパクトな方法があると思います。私はそのタイプのコンパクトな構文で何かを求めています。

3
Peter.O

私の答えは基本的に このトピックに関する他の質問 と同じです:

$ iconv -f UTF-16LE -t UTF-8 myfile.txt | grep pattern

他の質問と同様に、行末変換も必要になる場合がありますが、重要なのは、ネイティブツールを直接使用できるように、ファイルをローカルエンコーディングに変換する必要があるということです。

8
Warren Young

ウォーレンの答えの方が優れていると思います一般 * nixソリューションですが、このPerlスクリプトは私が望んでいたとおりに機能します(私のやや非標準的な状況の場合)。検索パターンの現在の形式を少し変更する必要があります。
from \x09\x0A\x09\x2A\x09\x30\x00\s09
から\x{090A}\x{092A}\x{0930}\x{0009}

それは特に私が求めていたものである1つのプロセスですべてを行います。

#! /usr/bin/env Perl
use strict;
use warnings;
die "3 args are required" if scalar @ARGV != 3;
my $if =$ARGV[0];
my $of =$ARGV[1];
my $pat=$ARGV[2];
open(my $ifh, '<:encoding(UTF-16LE)', $if) or warn "Can't open $if: $!";
open(my $ofh, '>:encoding(UTF-16LE)', $of) or warn "Can't open $of: $!";
while (<$ifh>) { print $ofh $_ if /^$pat/; }
1
Peter.O

インストール ripgrepユーティリティ UTF-16をサポートします。

例えば:

rg pattern filename

ripgrepは、UTF-16、latin-1、GBK、EUC-JP、Shift_JISなどのUTF-8以外のテキストエンコーディングでのファイルの検索をサポートしています。 (UTF-16を自動的に検出するためのサポートがいくつか提供されています。他のテキストエンコーディングは、-E/--encoding flag.で具体的に指定する必要があります)

すべての行を印刷するには、rg -N . filenameを実行します。

1
kenorb

ugrep(Universal grep)は、Unicode、UTF-8/16/32ファイルをサポートし、無効なUnicodeを検出して適切な結果を保証し、テキストファイルとバイナリファイルを表示します。高速で無料です:

grep UTF-8/16/32入力およびその他の形式を検索します。オプション-Qを使用すると、ISO-8859-1〜16、EBCDIC、コードページ437、850、858、1250〜1258、MacRoman、KOI8など、他の多くのファイル形式を検索できます。

一致するUnicode文字のパターンを指定するだけです。

ugrep -QUTF-16LE "ऊपर" filename

または16進数のコードポイントを使用:

ugrep -QUTF-16LE "\x{090A}\x{092A}\x{0930}" filename

詳細については、 GitHubのugrep を参照してください。

0
Dr. Alex RE