背景
- 以下の記事を見ました
- <JavaScript>特定の文字列で区切られたファイル名をそのファイル名の一部で一括変換するクイズ
- Javaでやれと言われた気がしたのでやります
- やりたいこと
環境
- Macでやってます
$ java -version
openjdk version "14.0.1" 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.1+7)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.20.0, JRE 14 Mac OS X amd64-64-Bit Compressed References 20200416_40 (JIT enabled, AOT enabled)
OpenJ9 - 05fa2d361
OMR - d4365f371
JCL - 5757187cae based on jdk-14.0.1+7)
事前準備
- 同じように元記事は
abc_test_ok_1_this.csv
・・・abc_test_ok_100_this.csv
のファイルを用意するところからワンライナーでやってるのでそこから
echo 'IntStream.range(1,101).forEach(i -> {try {Files.createFile(Paths.get("abc_test_ok_"+String.valueOf(i) + "_this.csv"),java.nio.file.attribute.PosixFilePermissions.asFileAttribute(java.nio.file.attribute.PosixFilePermissions.fromString("r--r--r--")));} catch (Exception e) {throw new RuntimeException(e);}})' | jshell -
- Javaはコンパイルが必要だからワンライナーは向かないと思われがちですが、最近のJavaではJShellというREPLツールが使えるのでできます。
- echoで書きつつ、パイプでjshellコマンドに渡しています。最後の - は余計な表示をしないようにしています。
- import文はものによって省略できます。
- パーミッションの書き方などがUnixベースなので、Windowsだと動かないと思います。
- ループはFor文で書いたら負けかなと思いましたので、特に意味なくStreamからのforEachつかいました。
- 改行込みで書くと以下になります。例外処理とかが面倒な感じですね。
IntStream.range(1,101).forEach(i -> {
try {
Files.createFile(Paths.get("abc_test_ok_"+String.valueOf(i) + "_this.csv"),
PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("r--r--r--")));
} catch (IOException e) {
throw new RuntimeException(e);
}
});
ファイルのリネーム
- ここからが本題です。
- といいつつ、いきなりで以下で動きました。
echo 'Path path1 = Paths.get(".");try{Files.list(path1).forEach(from -> {String intStr = from.toString().replaceAll("[^0-9]", "");try {Files.move(from, Paths.get(".",intStr + ".csv"));} catch (IOException e) {e.printStackTrace();}});} catch(IOException e) {e.printStackTrace();}' | jshell -
- 正規表現で数字だけ取ってファイル名にリネームしているので、フォルダ内に余計なファイルがあると動かない可能性があります。
- 現在のディレクトリのPathを取った後に、listで直下のものをがさっと取ってforEachで回しつつ、moveでファイルリネームしています。
- 改行込みで書くと以下になります。やはり例外処理とかが面倒な感じですね。(例外処理の後処理が上と違うのは特に意味がないです)
- (7/15追記)ラムダ式を使う形にリファクタリングしました。
Path path1 = Paths.get(".");
try{
Files.list(path1).forEach(from -> {
String intStr = from.toString().replaceAll("[^0-9]", "");
try {
Files.move(from, Paths.get(".",intStr + ".csv"));
} catch (IOException e) {
e.printStackTrace();
}
});
} catch(IOException e) {e.printStackTrace();}
}
おわりに
- 久しぶりにJShell触りました。さくっと動くのは良いですね。
- ファイル処理は前回の人と同じく、普段あまりやらないので調べながらやったので、よりよいやり方あればご指摘ください。