Posted at

NodejsでBashのsplitコマンドっぽい処理を書く


はじめに

Node.jsで重たいファイルを扱う際に、bashのsplitコマンドっぽく、

ファイルを行ごとに分割したかったので作ったものを備忘録として残す。

Bashのコマンドとオプションを合わせたので、Bashっぽく使えるのがポイント。


コード


bashのsplitコマンド


split.sh

$ split [OPTION]... [FILE [PREFIX]]



オプション(一部)


  • -l, --lines=NUMBER


    • 分割するファイルの行単位



  • -d, --numeric-suffixes


    • 指定あり: [PREFIX000, PREFIX001, PREFIX002...]

    • 指定なし: [PREFIXaaa, PREFIXaab, PREFIXaac...]



  • -a, --suffix-length=N


    • 出力ファイルに付加する文字列の長さ




Nodejs版


split.js

const fs = require('fs');

const readline = require('readline');

function createAlphabetSuffix(num, length) {

let i = num;
let str = '';

while (i > 0) {
str = String.fromCharCode(97 + (i % 26)) + str;
i = Math.floor(i / 26);
}

return str.padStart(length, 'a');

}

function createNumericSuffix(num, length) {
return String(num).padStart(length, '0');
}

module.exports = function split(file, options = {}) {

return new Promise((resolve) => {

let {
prefix = 'x',
lines = 100,
suffixLength = 3,
numericSuffixes = false
} = options;

const rs = fs.createReadStream(file);
const rl = readline.createInterface(rs);

let index = 0;
let ws;

rl.on('line', (line) => {

let i = index++;

if (i % lines === 0) {

ws && ws.close();

const suffixIndex = Math.floor(i / lines);
const suffix = numericSuffixes
? createNumericSuffix(suffixIndex, suffixLength)
: createAlphabetSuffix(suffixIndex, suffixLength);

ws = fs.createWriteStream(`${prefix}${suffix}`);

}

ws.write(line + '\n');

});

rl.on('close', () => {
ws && ws.close();
resolve();
});

});

};



オプション

オプション
初期値
説明

prefix
x
出力するファイルのベース名

lines
100
出力するファイルの行数

suffixLength
3
出力ファイルに付与する文字列の長さ

numericSuffixes
false
出力ファイルに付与する文字列を数値にするか


サンプル


useSplit.js

const split = require('./split');

(async () => {

await split('./largeFile.txt', {
prefix: 'smallFile',
lines: 10,
suffixLength: 4,
numericSuffixes: true
});

})();



result

$ node useSplit.js

$ ls | grep smallFile
# smallFile0000
# smallFile0001
# smallFile0002
# ...


最後に

意外に探しても見つからなかったので作ってみました。

他に良い方法があればご指摘ください。