サラリーマンのすらすらIT日記

IT関連を中心とした日々を綴ります。
--/--/--

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
2012/05/10

Windowsのsedにもバグが?!-その2

以前書いた「Windowsのsedにもバグが?!」に対して、多くのコメントをいただきました。ありがとうございます。いずれも「こうすればうまくいくでしょう」といった内容でした。対象となるテキストファイルの内容が実業務に関連することなので、内容をそのまま書くわけにいかなかったのですが、今回うまくいかないテキストファイルを作成してみたので、詳しく書いておきます。

まず、コメントのいくつかにあった「Windowsのコマンド・プロンプトのクォートのエスケープの問題」ですが、実は既にs/"//gの部分をスクリプトファイルにしてやっていました。それでもうまくいかないのです。それにそもそもs/"//と1つずつクォートを削除していくとできるのに(4回目の削除だけはダメですが)、gを付けて一遍にやろうとするとうまくいかない理由が私にはわかりません。

対象テキストファイルは次のようなものです。実業務に関連する内容は○で伏字にしました。この伏字のままでも、今回述べる不具合現象は発生します。

6;0;"2000/08/01";"○○○";"0123509 "
20;0;"1998/06/16";"○○○○ ○○○○○ ";"J11C-5-34 "
26;0;"1998/06/16";"○○○○○○ ";"J11C-4-18 "
26;0;"1998/06/16";"○○○○○○ ";"J11C-4-18 "
26;0;"1998/06/16";"○○○○○○ ";"J11C-4-18 "
26;0;"1998/06/16";"○○○○○○ ";"J11C-4-18 "
26;0;"1998/06/16";"○○○○○○ ";"J11C-4-18 "
26;0;"1998/06/16";"○○○○○○ ";"J11C-4-18 "
26;0;"1998/06/16";"○○○○○○ ";"J11C-4-18 "
26;0;"1998/06/16";"○○○○○○";""

テキストファイルの最初の10行だけを示しましたが、実際は376417行から成るテキストファイルです。実際の対象テキストファイルは11行目以降1つとして同じ行はありませんが、テスト用に作ったテキストファイルは10行目から最終行(376417行)までは全部同じ内容です。

このテスト用テキストファイルをこちらからダウンロードできるBinariesのZipファイル(Ver4.2.1となっていますが、解凍後のsed.exeファイルのVerは4.1.5.4013です)を解凍したsedを使いました。

スクリプトs/"//gをremoveQuote.sedという名前で保存し、上記テスト用ファイルをNG.txtとして、

sed -f removeQuote.sed NG.txt > NGLast.txt

を実行すると、今回述べている不具合が発生します。ご不審とあらば、これと同じテキストファイルを作成して、上記sed for Windowsをダウンロードして一度実行してみてください。きっと不具合が発生します。不思議なのは、このテスト用テキストファイルの1~9行目を削除すると、うまくいくこと。4つ目のクォートの前にたくさんのスペースがあることが原因かも、と前回書いたのはこのためです。

やはりこれはsed for Windowsのバグだと思います。

スポンサーサイト

コメント

そうなんですね。特定のバージョンに不具合があるのか、sed for Windows と名づけられている sed 全般に不具合があるのかわかりませんけど、少なくともご指定のプログラムには不具合があるということですね。

ちなみに、わたしの環境ではなんら不都合なく実行できました。たぶん、Windows に LaTeX をインストールしたときに一緒にインストールされた sed のようです(version 3.02 でした)。
2012/05/11(金) 13:25:56 |URL|通りすがり #- [編集]
コメントありがとうございます。

プログラムによるんですね。私がダウンロードしたものが、たまたま悪かったということですか。
最近Ubuntuを使うことが増えてきたので、UNIX系OSのコマンドはUbuntuで使うことが多くなりました。
Windowsでやってみる機会があれば、ご紹介いただいたプログラムを使ってみます。
2012/05/12(土) 00:59:06 |URL|sookibizviz #- [編集]
sedのハングアップ(2コアなのでCPUは50%消費)に遭遇して手軽な対策を探してる途中でこの記事の1の方を見かけたのでコメント。

ロケールの問題ではありませんか?

GnuWin32のsed 4.2.1(リソースではVer4.1.5.4013、以下gsed)とTeXに付属のsed 3.02(以下tsed)を提示されているデータの各種組み合わせで試験してみました。
gsed + NG.txt(sjis)→正常終了
gsed + NG.txt(utf8)→ハングアップ
gsed + OK.txt(sjis)→正常終了
gsed + OK.txt(utf8)→正常終了
tsed + NG.txt(sjis)→正常終了
tsed + NG.txt(utf8)→正常終了
tsed + OK.txt(sjis)→正常終了
tsed + OK.txt(utf8)→正常終了
どう見てもロケールの問題です。
デバッガで追いかけるとsetlocale(LC_ALL,"")によりシステムロケール(日本語Windowsなら通常はsjis)を処理するよう設定されたmbrtowc(次の文字は何バイトで構成されるのかを返す関数)が-2(不正なマルチバイト文字を検出してのエラー、の意)を返し、コレをエラー値ではなく-2バイトの文字として処理してしまうことで処理位置が後ろに戻り、その後また同じエラーに遭遇という流れを繰り返しているようです。
まぁバグといえばバグですが、不正なデータを入力してのハングアップなのでユーザにも問題がある・・・といえなくも有りません。
Unix的な解決方法は環境変数LC_***にja_JP.UTF-8等をセットすることなんですがWindowsでは環境変数は無視されますので、gsedで処理する場合は一旦sjisに変換して(Unicode文字を捨てて)処理するしかないでしょう。

ちなみにtsedではマルチバイト用の処理を一切行っていない(mb***を使わない)ので、英語アプリケーションで日本語を扱うためのバッドノウハウで対処可能です。
(例:sjisの「ソ」のような文字は二バイト目が「\」なので注意する「echo ミソ1|tsed -e s/ミソ(.)//g」)
(例:sjisの大文字小文字変換に注意する「echo デベハトップ|tsed -e s/デスクトップ/-/ig」)
補足。UTF-8のマルチバイトシーケンスは0x00-0x7FのASCII文字が含まれない為tsed+UTF-8でならばこれらのバッドノウハウは不要ですが、UTF-8自体の冗長性により同じ文字列に複数のバイト表現があるため、正規化されていないUTF-8テキストでは問題が発生する恐れがあります。

あ、多分mbrtowcのエラーチェック漏れはLinux版のsedにも有ると思われます。
参考:uraugee.txt-nifty.com/blog/2009/02/sed-a248.html
2012/06/09(土) 18:24:54 |URL|通りすがり #z7Xcv.4o [編集]
長大なコメント、ありがとうございます。
ロケールですか...時間を見て確認してみます。

2012/06/09(土) 18:31:12 |URL|sookibizviz #- [編集]

コメントの投稿

  • URL
  • コメント
  • パスワード
  • 秘密
  • 管理者にだけ表示を許可する

トラックバック

トラックバックURL:http://sookibizviz.blog81.fc2.com/tb.php/1191-a349e28f

■  カレンダー

09 | 2017/10 | 11
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -

■  プロフィール

sookibizviz

Author:sookibizviz
仕事の内容やソフトの紹介を交えながら、日々の悪戦苦闘を綴っていきます。

■  最新記事

■  最新コメント

■  最新トラックバック

■  月別アーカイブ

■  カテゴリ

未分類 (64)
BizViz (24)
IT (1119)
計量 (76)
環境 (26)
数学 (181)
ニュース (46)
本 (187)
音楽 (113)
囲碁 (5)
将棋 (26)
ブログ (14)
日記 (19)

■  FC2カウンター

■  検索フォーム

■  RSSリンクの表示

■  QRコード

QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。