WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:UNIX環境で日本語ファイル

0:[投稿] かな [2002/09/19 12:01 ][環境:WIN+IE UNIX系+Perl]

サーバにファイルといくつかのサイトからダウンロードし、
そのファイルに処理をしようとしています。
処理はコマンドの「find . -type f | xargs grep 'hoge'」などと
したいのですが、ファイル名に日本語や特殊文字が使われていると
xargsでエラーが発生してしまいます。

エラーは「Illegal byte sequence ファイル名」と出ます。

これを改善するためコマンドを実行する前に、ファイル名が日本語や
特殊文字を含む場合は、そのファイルを削除したいのですが、どのようにすれば効率よく出来るでしょうか?
私の考えたところでは以下のようなプログラムを作ってみたのですが、
なぜか時々getcodeの判定で、日本語を含むファイルなのに
eucだと判断されてて、削除されてない場合があります。


require "./jcode.pl";

$code = jcode::getcode(\$filename);
if($code){
    if($code ne "euc"){
        unlink($filename);
        next;
    }
}
if($filename =~ /( | )/){
    unlink($filename);
    next;
}
if($filename =~ /(\'|\~)/){
    unlink($filename);
    next;
}

よろしくおねがいします


1:[回答] B-Cus [2002/09/19 12:30 ]

OS は何? バージョンは何?

> ファイル名に日本語や特殊文字が使われていると

具体的な例は?

> なぜか時々getcodeの判定で、日本語を含むファイルなのに
> eucだと判断されてて、削除されてない場合があります。

具体的な例は?


> find . -type f | xargs grep 'hoge'

 % find . -type f | env LC_ALL=C xargs grep 'hoge'
とか。

GNU find & GNU xargs なら find -print0 | xargs -0 とか。


2:[質問] かな [2002/09/19 13:52 ]

お返事ありがとうございます。
OSなどまったく記述してなくてすいませんでした。
OSはsolaris6です。Perlは5.004を使用してます。

>> ファイル名に日本語や特殊文字が使われていると
>具体的な例は?
ファイル名が「日本語.txt」や「what's.txt」などのときです。

>> なぜか時々getcodeの判定で、日本語を含むファイルなのに
>> eucだと判断されてて、削除されてない場合があります。
>具体的な例は?
調べたところ、ファイル名に半角カナ(例:ニホン.txtなど)が
使われているときは、getcodeで判定できないようですね。
なにかいい方法はあるのでしょうか?

>% find . -type f | env LC_ALL=C xargs grep 'hoge'
>とか。
アドバイスありがとうございます。
確かにこの方法だとxargsエラーは発生しなくなり、
grep処理はできるようになるのですが、他のPerlプログラムで
全てのファイルを処理したいと考えているので、
半角カナが入っているファイルは基本的に削除したいと思っております。


3:[質問] 29歳からのPerl [2002/09/19 22:47 ]

便乗の質問で申し訳ないのですが、ソラリ6のファイル名で、「1バイトだけカナ(0xA1〜0xDF)」で構成されているものがあるのでしょうか?

jcode::getcodeですが、半角カナだけを判断基準にして場合、判断ミスがあると明記されています。
ただ、getcodeの問題というより、この場合判断できないですから、しょうがないですよね。


4:[回答] ふじ [URL] [2002/09/19 23:54 ]

ファイル名に SJIS と EUC が混在しているということは考えにくいです。

Solaris ならおそらく EUCでしょうから、EUC という前提で
ASCII以外の文字が含まれているかどうか判断すればよいのでは。

http://www.din.or.jp/~ohzaki/perl.htm#JP_Exist


5:[回答] B-Cus [2002/09/20 01:20 ]

> ファイル名が「日本語.txt」や

ファイル名が日本語だからダメなのではなく、ファイル名のエンコーディングと、
xargs 実行時の locale のエンコーディングが合っていないのが問題です。

 % setenv LC_ALL ja_JP.eucJP
 % echo 日本語.txt | xargs
 日本語.txt
 % echo 日本語.txt | euctosj | xargs
 xargs: 入力ファイルが壊れています。: バイトシーケンスが正しくありません。

> 「what's.txt」などのときです。

これは別問題。
  grep hoge what's.txt
とするとエラーになるのと同じ。


今回の問題で、「半角カナが入っているファイルは除外する」というなら
 http://www.din.or.jp/~ohzaki/perl.htm
を参考に
 $ascii = '[\x00-\x7F]';
 $twoBytes = '[\xA1-\xFE][\xA1-\xFE]'; # 半角カナは除外
 $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
 if ($str =~ /^($ascii|$twoBytes|$threeBytes)+$/) {
    print "正しい EUC-JP の文字列 (ただし半角カナを除く)\n";
 }
でいいんでしょうが、結局「what's.txt」問題は解決されません。
' を除いたとしても、> や & や | など、アプリにとって危険な
文字はたくさんあります。

よって、
 - ファイル名は英数字に限定する。
 - s/([^-_a-zA-Z0-9])/sprintf("%%%02lX",unpack("C",$1))/eg;
   などと、URL エンコードしたファイル名で保存する。
といった方法をお勧めします。

# もしインターネット上で不特定多数の人間が利用するのであれば特に。


> ファイル名で、「1バイトだけカナ(0xA1〜0xDF)」で構成されている
> ものがあるのでしょうか?

UNIX 一般に言えることですが、ファイル名は OS から見ればただの
バイト列なので、作ろうと思えば何でも作れます (`/' と NULL は
ダメですが)。

> ファイル名に SJIS と EUC が混在しているということは考えにくいです。
> Solaris ならおそらく EUCでしょうから、

うーん、誤解を招くような書き方じゃないでしょうか。

LC_ALL=ja_JP.ujis にすれば全てが Shift_JIS になるわけで、
一般論としては誤りでしょう。まぁ EUC-JP 環境の方が多い
のは確かでしょうけど。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World