異なるシステム間でデータをエクスポート・インポートする場合、CSV ファイルを用いるケースが割と多いかと思います。
そして、そのデータが数千行、あるいはそれ以上ある場合、インポート先システムの仕様や負荷・所要時間等を考慮し、複数回に分けたほうがよいこともあります。
しかし、テキストエディタや Excel を使って手作業で分割するのはとても面倒です。
そこで、PowerShell で CSV ファイルを分割するためのスクリプトを書いてみました。
(2015 年 4 月 21 日の記事の逆です。)
せっかくなので先日 Mac にインストールした Powershell 7.1.1 を使ってみました。
(ファイルは全てカレントディレクトリにあるものとします。)
分割する CSV は、12 名分の名簿「members.csv」です。
これを 5 名ずつ分割し、 「members-1-3.csv」、 「members-2-3.csv」、 「members-3-3.csv」の 3 ファイルにすることを目指します。 |
|
< 1 > 兎にも角にも、まずは「members.csv」を読み込み、変数「$original」とします。 $original = import-csv members.csv
< 2 > $whole = ($original).count
【余談】
< 3 > 単純に割り算すれば、「12÷5=2.4」となります。 $number = [math]::ceiling($whole/5) ※ 5,000 名ずつ分割したい場合は、末尾の値を 5,000 にします。
ここまでが下準備です。
< 4 > しかし、Powershell の場合は「一番上の行」を「ゼロ」行目として扱います。 $original[0..4] という記述になります。 次は $original[5..9] で、最後は $original[10..14] です。 実際のスクリプトにおいては、数字の部分は変数で記述する必要があります。(後述)
< 5 > While 構文は「条件」と「処理」の 2 部から成り、それぞれ ( ) と { } で括ります。 while (繰り返す条件) {繰り返す作業内容}
< 6 > Powershell の作法(?)に従うなら最初は「ゼロ回目」とすべきなのかもしれませんが、分かりやすくするため、「1」から始めます。 $time = 1 ※ この最初の変数定義は繰り返す作業内容に含まれないため、while 構文の直前に実行します。
処理を一回終えるたびに、$time に「1」を加算します。 $time++ ※ この加算は、繰り返す作業内容に含まれます。
<7> while ($time -le $number) 【余談】
< 8 > $original[($time*5-5)..($time*5-1)] | Export-Csv -path members-$time-$number.csv -encoding Unicode 前半(パイプ記号の左側)は、< 4 > の記述を変数を利用して書き換えたものものです。 後半(パイプ記号の右側)で、前半の実行結果を新規の CSV ファイルとして出力しています。
<まとめ> $original = import-csv members.csv $whole = ($original).count $number = [math]::ceiling($whole/5) $time = 1 while ($time -le $number) { $original[($time*5-5)..($time*5-1)] | Export-Csv -path members-$time-$number.csv -encoding Unicode $time++ }
|
|
この内容を「script.ps1」として保存し、 |
Powershell で実行します。
すると意図した通りに分割され、
「members-1-3.csv」、
「members-2-3.csv」、
「members-3-3.csv」の 3 ファイルが出力されました。
めでたしめでたし。
【余談】
Windows 10 (20H2, OS ビルド 19042.746) の Powershell 7.1.1 でも、全く同じ記述で全く同じように動作してくれました。
Powershell 5.1 では、Export-Csv コマンドレットに「-NoTypeInformation」オプションを付けておかないと、
出力されるファイルの先頭に「#TYPE System.Management.Automation.PSCustomObject」という1行が追加されてしまいます。
しかし 7.1.1 では、-NoTypeInformation オプションが無くとも、この1行は追加されませんでした。