3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

<JavaScript>特定の文字列で区切られたファイル名をそのファイル名の一部で一括変換するクイズ

Last updated at Posted at 2020-07-13

背景

やりたいこと

  • フォルダの中にabc_test_ok_1_this.csv・・・abc_test_ok_100_this.csvのファイルが入っている
  • これらを1.csv・・・100.csvにリネームしたい
  • ということだと思う(斜め読みしたから違うかも)
  • これらをコマンドラインでワンライナーで実現するというもの

環境

node -v
# v14.5.0

事前準備

  • 元記事はabc_test_ok_1_this.csv・・・abc_test_ok_100_this.csvのファイルを用意するところからワンライナーでやってるのでそこから
node -e "const fs=require('fs');[...Array(100).keys()].forEach(i=>fs.writeFile('abc_test_ok_'+(i+1)+'_this.csv','',()=>{}));"
  • nodeコマンドはnode main.jsのようにしてファイルを実行できるが、node -e "console.log('Hello')"のように-eオプションをつけるとその後をEvalするのでファイルに書かなくても直接実行できる
  • ちゃんと改行するとこんな感じ
const fs = require('fs');

[...Array(100).keys()].forEach(i => {
  fs.writeFile(`abc_test_ok_${i + 1}_this.csv`, '', () => {});
});
  • [...Array(100).keys()]で要素数100個の配列を作っています
    • .kyes()としてるので配列の各要素には0〜99の値が格納されます
    • [0, 1, 2, ... 98, 99]といった具合
  • これをforEachしてるので100回ループが回ってます
  • ファイルの作成にはfs.writeFile('ファイル名', 'ファイルの内容', callback)を使っています
    • ファイル名はお題の名前にしてindexを埋め込んでいる
    • ファイルの中身は指定がなかったので空っぽに
    • コールバックはとりあえず今回はいらないので空の関数
  • という感じで実行するとabc_test_ok_1_this.csv・・・abc_test_ok_100_this.csvが作成されました

ファイルのリネーム

  • ここが本題でしょうか
  • フォルダの中にあるabc_test_ok_1_this.csv・・・abc_test_ok_100_this.csvのファイルを1.csv・・・100.csvにリネームします
node -e "const fs=require('fs');fs.readdir(__dirname,(error,files)=>{files.forEach(file=>{fs.rename(file,file.match(/abc_test_ok_(.*)_this.csv/)[1]+'.csv',() => {},);});});"
  • さっきと同じくnodeコマンドの-eオプションを使ってワンライナーで実現しています
  • 改行するとこんな感じ
const fs = require('fs');

fs.readdir(__dirname, (error, files) => {
  files.forEach(file => {
    fs.rename(file, file.match(/abc_test_ok_(.*)_this.csv/)[1] + '.csv', () => {});
  });
});
  • fs.readdir('ディレクトリ', callback)を使ってディレクトリの中のファイル一覧を取得しています
    • 第1引数はカレントディレクトリでいいので__dirnameを定義
    • 第2引数はファイル名の一覧を処理する関数を定義
  • filesにファイル名の一覧が入っているのでfiles.forEach(file => { ... }でループを回しています
  • fs.rename('変更前のファイル名', '変更後のファイル名', callback)を使ってリネームしています
    • 変更前のファイルはループで回ってくるfile
    • 変更後のファイル名は正規表現で必要な部分を引き抜いています
    • callbackは今回は不要なので空の関数
  • これでフォルダの中にあるabc_test_ok_1_this.csv・・・abc_test_ok_100_this.csvのファイルを1.csv・・・100.csvにリネームできました
    • 余計なファイルがあったときの処理とかはいったん無視しました

終わりに

  • ちょっとしたスクリプトを書くのは息抜きの暇つぶしにいいですね。
  • Nodeでファイルの読み書きなんてほとんどやったことないのでググりながらやりました。もっとかっこいい書き方あるかも。
  • 次は誰かPythonとかRubyとかでお願いします。

参考

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?