PowerSehll

csv,txtファイルを指定した行数で分割して出力するPowerShell

PowerSehll

こんにちは! 健史です。

CSVやTEXT形式のファイルのデータ件数が多すぎて、メモ帳やExcelで開けないと

・データを簡単に分割できないかな?
・しかも専用のツールをインストールしないで

と思われることでしょう。

Windowsパソコンやサーバであれば、PowerShellで簡単にできます。

以下のPowerShellをメモ帳などで拡張子[.ps1]にして、分割したいファイルがあるフォルダ内に保存し、右クリックから[PowerShellで実行]で分割されます。

$split_cnt=1; cat .\分割前ファイル名.csv -ReadCount 分割件数 | % { $_ > 分割後ファイル名$split_cnt.csv;$split_cnt++ }

例えば分割するファイル名が[infile01.csv]、1000件単位に分割したい、分割後のファイル名は[bunkatsu1.csv][bunkatsu2.csv]・・・の場合は

$split_cnt=1; cat .\infile01.csv -ReadCount 1000 | % { $_ > bunkatsu$split_cnt.csv;$split_cnt++ }


上記を保存しておき別のファイル名を分割したい場合、修正箇所が分かりづらかったり確認メッセージがなかったりするので、ちょっとアレンジして作成してみました。

処理結果は、上記を実行した場合と同じです。

スポンサーリンク

実行イメージ

1.以下[2.]のPowerShellの3ヵ所を意図する内容に修正して保存

①分割するファイル名
②分割後のファイル名
「①分割対象ファイル名」と同じでもよいですが、見た目をわかりやすくするために最後に[_](アンダーバー)などつけることをおすすめします。
③分割件数
上記では①を5件単位に分割します。
Excelやエディタで開ける件数を指定されると思いますが、それであっても「100万件のデータを開くのは時間が掛かる」という場合は、意図する内容に応じた値にして頂ければと思います。

2.上記プログラムと分割対象のファイルを同一フォルダに格納

3.PowerShellプログラムを[右クリック]→[PowerShellで実行]

4.上記[1.]で指定した内容が表示され、確認メッセージが表示される
・分割件数のみ変更可能で変更する場合は変更する値を入力
・変更しない場合は何も入力しない
・終了する場合は0を入力
してEnterキー

5.終了メッセージが表示される
・内容を確認してEnterキー

6.フォルダ内の分割されたファイル

ハードコピーは載せませんが、[テスト用分割ファイル_1.csv][テスト用分割ファイル_2.csv]は、1~5件目まで、6~10件目のデータに分割されています。

PowerShell

#######################################################################
# ①分割するファイル、②分割後のファイル名、③分割件数 を指定、
#######################################################################
$infile = "テスト用入力ファイル.csv"
$outfile = "テスト用分割ファイル_"
[int]$cns_cnt_split = 5
#######################################################################
# 処理の中で使う件数を定義
#######################################################################
[int]$tmp_cnt = 0
#######################################################################
# 処理開始
#######################################################################
Write-host ファイル分割処理開始します!
Write-host "入力ファイル:" $infile
Write-host "出力ファイル:" $outfile
$edt_cnt = "{0:#,#}" -f $cns_cnt_split
Write-host "分割件数:" $edt_cnt "件`r`n"

$ac_cnt =(Read-Host 上記以外で分割する場合は値を入力してください。 `
    `r`n既定値の場合は空白でEnterキー、終了する場は0でEnterキー`r`n)

if([string]::IsNullOrEmpty($ac_cnt))
{
    Write-Host 既定値で処理します。
    $tmp_cnt = $cns_cnt_split 
}
else
{
   if([int]::TryParse($ac_cnt,[ref]$tmp_cnt))
   {
       if( $tmp_cnt -eq 0 )
       {
           Write-Host 分割せずに終了します!
       }
       else
       {
           $edt_cnt = "{0:#,#}" -f $tmp_cnt
           Write-Host "分割件数を"$edt_cnt" に置き換えます。"
           $cns_cnt_split = $tmp_cnt	
       }
   }    
   else
   {
       Read-Host 受け取った値が数字でありません。`r`n `
       分割せずに終了します!
       $tmp_cnt = 0
   }
}

#$tmp_cnt = 0 の時は、分割処理しない
if($tmp_cnt -ne 0)
{
#$tmp_cnt ≠ 0の時は、ファイル分割
    $cnt_split=1; cat .\$infile -ReadCount $cns_cnt_split | % { $_ > $outfile$cnt_split.csv;$cnt_split++ }
    Get-ChildItem
    Read-host ファイル分割処理終了!`r`n
}

処理の説明

概要

1.わかりやすくするために、PowerShellの先頭で設定値を変数として定義

2.設定値を表示し、分割件数のみ変更可能とし、また終了する場合は0を入力することで終了

3.入力値をチェック
1).何も入力しなかった場合は、設定値を変数[tmp_cnt]にセットして
2).入力値[ac_cnt]が数字の場合は、[tmp_cnt]にセットする
①.[tmp_cnt]が0の場合は、終了する旨のメッセージを表示する
②.[tmp_cnt]が0以外の場合は、分割件数を置き換える旨のメッセージを表示し、[tmp_cnt]を[cns_cnt_split]に置き換える
3).入力値[ac_cnt]が数字でない( 2).でない場合)は、その旨のメッセージを表示し、[tmp_cnt]に0をセットする

4.[tmp_cnt]が0でない場合に
1).分割処理を実行する
2).ディレクトリ情報を表示する
3).分割処理終了の旨のメッセージを表示する

PowerShellは処理をジャンプするGoTo命令がないので、[tmp_cnt]を使って処理を制御するようにしました。

「GoTo命令は処理をわかりにくくする」との理由から「使わない」といった考えがありますが、上から下への単に処理をスキップする目的であれば分かりやすく良いと思っています。

GoTo命令を使わずIf文で制御するのは、If文の終わりまでが長くなったり複雑になったりして、かえってわかりにくくなることもあります。

補足

コマンド一つひとつは説明せず、わかりにくいと考える部分を説明します。

・PowerShellのコマンド1行が長くなってしまう場合の改行
例えば以下です。上の行を下の行にしました。

$ac_cnt =(Read-Host 上記以外で分割する場合は値を入力してください。`r`n規定値の場合は空白でEnterキー、終了する場は0でEnterキー`r`n)

$ac_cnt =(Read-Host 上記以外で分割する場合は値を入力してください。 `
    `r`n規定値の場合は空白でEnterキー、終了する場は0でEnterキー`r`n)

バッククォート[`]を使います、1文字空白を空けて。

バッククォートは、Pの右キーの上の文字で、Shiftキーを押しながら該当キーを押します。

画面に表示する文字の途中でバッククォートで改行すると、1文字空白が挿入されます。

バッククォートは区切りのよいところで挿入する必要があります。

ちなみに上記PowerShellでは、いろいろ試す目的から[`r`n]の前後で改行するように変えています。

・Read-Hostの最後に改行マーク[`r`n]を入れた理由
上記のPowerShellコーディング上の改行とは異なり「実行時に画面に表示される文字を改行する」改行です。

Read-Host命令で入力待ちになりますが、Read-Host文字の最後尾に入力待ちの意の文字[:]が表示されます。

最後のメッセージ「Read-Host ファイル分割処理終了!」の場合は、

    ファイル分割処理終了!:  ・・・入力待ち

となります。

ですが、「Read-Host ファイル分割処理終了!`r`n」とすると、

    ファイル分割処理終了!
    :  ・・・入力待ち

となります。

表示する文字と入力待ちの行を分けたかったためにやってみました。

最後に

単にデータを分割する1行だけの処理では面白みがなく、知識習得のためにも「PowerShellに触れてみよう!」と作成してみました。

PowerShellには実行権限設定があって、最初は実行できず躓いたりしました。

PowerShellにも多くの機能があって、いろんなことができそうです。

PowerSehll
スポンサーリンク
- 面白かったらシェアお願いします! -
健史をフォローする
自分で改善

コメント