Invalid byte 1 of 1-byte UTF-8 sequence

Play frameworkで作ったプロジェクトをnetbeansifyしてNetBeansで作業してたところ、以下のエラーが出てプロジェクトが読み込めなくなった。

Invalid byte 1 of 1-byte UTF-8 sequence

どうやら以下のファイルがUTF-8でないことが原因らしい。

プロジェクトディレクトリ/nbproject/project.xml

今回は何故か文字コードS-JISになっていた。
UTF-8にして保存したら無事読み込めた。

sedコマンドで半角英数を全角英数に置換する.

半角英数を全角英数に置換する.

sedコマンドを使う.

hoge1.csvの半角英数を全角英数に置換し,hoge2.csvに出力する.

$ sed 'y/abcdefghihklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890/' hoge1.csv > hoge2.csv

かっこわるいけど,一番わかりやすい.

WindowsからMac OS X Lionにデータを転送する.

Mac側の設定

  1. システム環境設定の共有からリモートログインを有効にする.
  2. ifconfigコマンドでIPを取得.
  3. コンピュータ名を忘れたときはwhoamiコマンドでコンピュータ名を取得.

Windows側の(FileZillaを用いた)設定

  1. FileZillaMacに接続する設定を以下の通り行う.

ホスト:  sftp://xxx.xxx.xxx.xxx
ユーザ名: hogehoge (whoamiコマンドで出てきたコンピュータ名
パスワード: Macで設定しているパスワード
ポートの設定は不要

あとはFileZillaをいつも通り使えばよい.

ディレクトリ内の文書データをすべてUTF-8に変換

Windowsで作ったcsvデータをUbuntuで開くとき,文字コードの変換が必要.

そんなとき,Ubuntunkfコマンドを使えば良い.

インストール

sudo apt-get install nkf

最近のUbuntuはインストールされてないコマンドが入力されるとインストールを促す賢い機能がついているので,画面の表示に従えば大抵インストールできる.

nkfコマンドの使い方

1.文字コードを確認する

$ nkf -g hogehoge.csv

2.文字コードUTF-8に変換する

$ nkf -w --overwirte hogehoge.csv

このほかにもオプションを変えるとShift-JISなどにも変換できる.

  • Shift-JIS : -s
  • JISコード : -j
  • EUC-JP : -e

注意:--overwriteオプションを付けなければ,変換後のデータが真っ白になる.

ディレクトリ内すべてのデータの文字コードUTF-8に変換する

$ nkf -w -Lu --overwirte *.csv

改行をUnix形式に変換するため-Luオプションを用いる.
改行をWindows形式に変換するときは-Lwオプションを用いる.

ライブラリを使わずにJavaからRを使う

統計解析器RをJavaで使う。
RをJavaで扱うライブラリもあるようだけど、
ライブラリの中を理解するのが大変そうなので、
ライブラリを使わずにRの出力をJavaで受け取りたい。

というわけで、やってみた。

環境

Ubuntu 10.04
Netbeans 6.8

コード

help()コマンドを実行した時の出力を受け取る。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

/**
 *
 * @author Syu_Syu
 */
public class Rcmd {
    public String commander()throws IOException {
        String result = new String();

        ProcessBuilder builder = new ProcessBuilder("/usr/bin/R","-q","--no-save");
        Process process = builder.start();
        OutputStream os = process.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));

        bw.write("help()");
        bw.flush();
        bw.close();

        InputStream is = process.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line_tmp = new String();
        String line = new String();
        while((line_tmp = br.readLine()) != null){
            line += line_tmp +"\n";
            System.out.println(line_tmp);
        }
        br.close();

        InputStream stream = process.getErrorStream();
        while(true){
            int c = stream.read();
            if(c == -1){
                stream.close();
                break;
            }
            System.out.print((char)c);
        }

        result = line;
        return result;
    }
}

ライセンス表示の省略

Rを起動すると以下の文章が表示される。

R version 2.10.1 (2009-12-14)
Copyright (C) 2009 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

Rは、自由なソフトウェアであり、「完全に無保証」です。 
一定の条件に従えば、自由にこれを再配布することができます。 
配布条件の詳細に関しては、'license()'あるいは'licence()'と入力してください。 

Rは多くの貢献者による共同プロジェクトです。 
詳しくは'contributors()'と入力してください。 
また、RやRのパッケージを出版物で引用する際の形式については
'citation()'と入力してください。 

'demo()'と入力すればデモをみることができます。 
'help()'とすればオンラインヘルプが出ます。 
'help.start()'でHTMLブラウザによるヘルプがみられます。 
'q()'と入力すればRを終了します。 

標準出力をStringで取ってきているので、この文章も取ってきてしまう。
そこで、非表示にするオプションを使う。

ProcessBuilder builder = new ProcessBuilder("/usr/bin/R","-q","--no-save");

この"-q","--no-save"がオプション。
 -qでライセンスを非表示にできる。
 --no-saveで実行したRを保存しない設定にしている。

複数のコマンド入力

以下のコードでhelp()コマンドを入力している。

bw.write("help()");
bw.flush();
bw.close();

例えば、続けてgetwd()コマンドを入力したい時は、以下のようにする。

bw.write("help()\n");
bw.flush();
bw.write("getwd()");
bw.flush();
bw.close();

または、以下のように、\nで繋げて書いても良い。

bw.write("help()\ngetwd()");
bw.flush();
bw.close();

エラー処理は必須

以下のコードは、エラー処理として絶対に必要。

        InputStream stream = process.getErrorStream();
        while(true){
            int c = stream.read();
            if(c == -1){
                stream.close();
                break;
            }
            System.out.print((char)c);
        }

このエラー処理がないと、うまく動かない。

おわり

取ってきたStringは、以下のようにコマンドも出力されている。

> getwd()
[1] "/home/username/NetBeansProjects/projectname"
> 

そのため、別のプログラムで必要な部分だけ抽出してやる必要がある。

VertualBoxでWindows7(Host)とUbuntu10.04(Guest)のフォルダを共有する

目的

VertualBoxでWindowsUbuntuのファイルを共有する

前提

  • VerturlBox 3.16
  • ホストOSはWindows7 64bit
  • VerturlBoxで動くゲストOSはUbuntu10.04
  • Ubuntu側にゲストアディッションがインストールされている

作業

Windows
  • 共有するフォルダを作成する。
    • 例)マイドキュメント以下にVbShareフォルダを作成
Ubuntu
  • VertualBoxでUbuntuを起動
  • VertualBoxメニューの「デバイス」から「共有フォルダ」を開く
  • 「共有フォルダ」にフォルダを追加する。
    • 右側にある「+」が描かれたアイコンで、Windows側にあるフォルダを選べる
  • OKを選択してUbuntuに戻る
  • Ubuntu側の共有するフォルダを作成する。(GUIで作っても、以下のコマンドで作っても良い

% mkdir vbshare

  • 共有フォルダをマウントするため、端末を起動し、以下のコマンドを入力

% sudo mount -t vboxsf VbShare /vbshare


これでフォルダ共有完了

半角スペースを含むアルファベットで構成された複合名詞を抽出する

形態素解析した結果から、複合名詞を抽出するときに出現した問題

複合名詞(格フレームではない)を抽出するときは、基本的に名詞の連続を抽出する。
しかし、形態素解析の結果から、名詞の連続を単に追記して抽出した場合
以下のようなスペース区切りの文節があると、スペースを除去してしまう。

  • System as a Service
  • Information Technology
  • D V D

MeCabのオプションでスペースをそのまま認識させたり、
すべての半角文字を全角に直したら、解析結果にもスペースが発生して、追記するだけでも問題なく複合名詞が抽出できる・・・らしいw

今回は、半角のまま、MeCabのオプションも利用せずに、半角スペースを含んだ複合名詞を抽出する。

前提

コード

アルファベット判定

String strの中がすべてアルファベットならtrueを返す。
さらに、アルファベットの中に半角スペースがあっても、trueを返す。

public boolean dicisionAlphabetNoun(String str){
    boolean result = false;
    Pattern az_pattern = Pattern.compile("[a-z|A-Z]");
    String[] _str = str.split(" ");
    if(_str.length >1){
        int _count =0;
        for(String s : _str){
            if(this.dicisionAlphabetNoun(s)){
                _count++;
            }
        }
        if(_count == _str.length){
            result = true;
        }
    }else{                
        char[] strtoChar_array = str.toCharArray();
        int bool_count= 0;
        for(char c : strtoChar_array){
            Matcher az_matcher = az_pattern.matcher(String.valueOf(c));
            if(az_matcher.matches()){
                bool_count ++;
            }
        }
        if(bool_count == strtoChar_array.length){
            result = true;
        }
    }
    return result;
}
アルファベット判定を行った後、複合名詞として追記するコード

これはまぁアルファベット判定を呼んでスペース追記していくだけなので適当に・・・w

if(dicisionAlphabetNoun(result)){
    if(dicisionAlphabetNoun(chanks.morphs.get(i+count).Appearance)){
        result += " " + morphs.get(i+count).Appearance;
    }
}else{
    result += chanks.morphs.get(i+count).Appearance;
}

感想

半角のままでもできるけど、とてもめんどくさいw