メモ : 【Java】読み込んだcsvを加工(条件で抽出、変更)して出力する　


#**背景**
職場の方がラズベリーパイで大気やら紫外線やらのデータを収集しています。
今やっているプロジェクトでグラフ描画するのに、そのデータを拝借してサンプルに使おうと思ったら、
途中に変なデータが混じっていたので、整形しないと使えないなーって書いたコードを書き残します。

![haikei.png](https://qiita-image-store.s3.amazonaws.com/0/237418/36c4f0d9-7b86-d462-bf49-5d6539d41501.png)

#**こんなデータ**
**`yyyy/mm/dd hh:mm:ss,大気圧(hPa),温度(℃)`** で0時から23時59分59秒まで毎秒データを取得
たまーに大気圧データの頭に10が付いているデータが混じっている様子

```20180712.csv
2018/07/12 00:00:00,1014.44,28.59
2018/07/12 00:00:01,1014.44,28.59
2018/07/12 00:00:02,1014.46,28.62
2018/07/12 00:00:03,1014.45,28.62
2018/07/12 00:00:04,1014.44,28.59
2018/07/12 00:00:05,1014.45,28.62
2018/07/12 00:00:06,101014.45,28.59
2018/07/12 00:00:07,1014.45,28.62

　　　　　　～　中略　～

2018/07/12 23:59:58,1006.29,28.66
2018/07/12 23:59:59,1006.28,28.62
```
#**やりたいこと**
**CSVを読み込んで、必要な加工をして、別名のCSVに出力したい。**
-　毎秒は不要なので1分毎のデータを書き出したい。(毎分00秒だけ抽出する)
-　00秒の大気圧データに101014.45みたいな数値が入っていたら1014.45に直してデータを書き出したい。


#**完成したコード**

```test.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class test{

    public static void main(String[] args) {
        process("20180712.csv",  ":00,","output.csv");
    }

    public static void process(String read_file, String searchString, String output_file){

        try(FileReader fr = new FileReader(read_file);BufferedReader br = new BufferedReader(fr);
            FileWriter fw = new FileWriter(output_file);BufferedWriter bw = new BufferedWriter(fw)){

            String line;
            while ((line = br.readLine()) != null) {
                Pattern p = Pattern.compile(searchString);
                Matcher m = p.matcher(line);
                if (m.find()){
                    String[] csvArray;
                    csvArray = line.split(",");
                    String time  = csvArray[0];
                    float press = Float.parseFloat(csvArray[1])%10000;
                    String pressure = String.format("%.2f", press);
                    String temperature  = csvArray[2];
                    String outputLine = String.join(",",time,pressure,temperature);
                    bw.write(outputLine);
                    bw.newLine();
                }else{ 
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
```
#**:pencil:  やっていること　**
　　processに読込むﾌｧｲﾙ名 , 検索文字 , 出力ﾌｧｲﾙ名 の３つの引数を渡してます。
　　　　process("20180712.csv",  ":00,","output.csv");

❶ Pattern と Matcher を使用して 0秒(":00,") の行を検索
❷ 00秒を含む行が見つかったら、Stringの配列(csvArray)に , (カンマ) でsplitして入れる
❸ 大気圧データ(csvArray[1])は小数なのでString型からfloat型に変換する
　　※ついでに10000で割った 余りを値に設定する。101014.45を10000で割ると余りは1014.45
❹ float型のデータを再度String型に変換する
　　※ついでに小数第二位以下を四捨五入して値に設定する。
❺ 各配列の値を, (カンマ) で繋げる
❻ 1行出力して改行する

❶～❻までを読込むﾌｧｲﾙの行数分繰り返す

---

#**:pencil:  メモ　**
######**検索するのに使った Pattern と Matcher**
MatcherはPattern.matcher()メソッドに文字列を渡して作成できる。
マッチ判定の結果がtrueかfalseで返される。

```java
Pattern pattern = Pattern.compile("う"); //検索したい文字列　"う"　を設定する Pattern を作成
Matcher matcher = pattern.matcher("あいうえお"); //検索対象の文字列　"あいうえお"　を検索対象にするよっていう matcher　を作成

matcher.find()       // 部分的にマッチするかの判定
matcher.lookingAt()  // 先頭からマッチするかの判定
matcher.matches()    // 完全にマッチするかの判定
```

######**関数電卓**
はじめてWindowsの標準電卓以外の電卓機能を使ったのでメモ
![電卓.png](https://qiita-image-store.s3.amazonaws.com/0/237418/92a097bb-7a87-7dfd-f789-329ba069ef5a.png)

101014.45を10000で割ったときのあまりを求める時
101014.45　Mod　10000 = 1014.45
![関数電卓.png](https://qiita-image-store.s3.amazonaws.com/0/237418/3d7b4ff4-c73e-4bc9-6756-9d5a96ed0bff.png)