csvで特定の月だけ抜き出すPowershellの作成
Powershellを使ってみたい & 仕事につかえそうだと思ったので作成にチャレンジしてみました。
設計
初期イメージ
1. csvファイルの読み込み
2. 特定の行、カラムの判定(今回は日付)
3. 行の削除 or ファイルへの出力
実際のソース
# 処理対象のフォルダは同一の場所にあるものとする
# $csvファイルのリストを取得する。
$csvFileList = Get-ChildItem "*.csv";
# 先月以外の行を削除するため先月の文字列を取得
$now = Get-Date;
$prevMonth = $now.AddMonths(-1);
$formatDate = $prevMonth.ToString("yyyy/MM/");
$formatDate = '*' + $formatDate + '*';
# ファイル名用の先月の文字列を取得
$fileNameDate = $prevMonth.ToString("yyyyMM");
foreach($csvFile in $csvFileList)
{
# csvを読み込む カラム名が無い or 特殊な場合は指定が必要
# このコードでは3カラムのみ指定しているため3カラムしか出力されない
$item = Import-Csv $csvFile -Encoding default -Header "Id","Number","Date";
#3行目から開始する特殊なcsvなのでfor
# lt は < の意味を持つ
for($i=3; $i -lt $item.Count;$i++)
{
$columnValue = $item[$i].Date;
# 先月の内容でない場合は削除する
if ( $columnValue -notlike $formatDate)
{
$item[$i] = $null;
}
}
# 先月 + ファイル名で新しいファイル名の作成をする
$fileName = $fileNameDate + $csvFile.Name;
# 先月の内容を新しいファイルに出力する
$item | Out-File "$fileName" -Encoding default;
}
作成時に躓いた箇所
- 文字コード
ファイル出力時に文字化けしていた。
→ Encodeを入れることで解決 ShiftJisの時はdefault,UTF8の時はUTF-8を入れる - 含むの判定
今回は特定の月の文字列が含まれていたら~という処理にしようと考えていた。
最初に調べたときにcontainsが出てきたのでcontainsを使用したが上手くいかなかった。
調査の結果object、配列等の時にcontainsを使用することが分かり、likeに変更することで想定通りの処理ができた。 - ループ処理
読み込むcsvの仕様上特定の行から始めるループになっているが、 本来であれば全ての行を読み込むまで処理を行うforeachが使用できるので、そちらを使用したほうが分かりやすい。
まとめ
始めてPowershellを使用してみたが、非常に色々なことができそうに感じた。
繰り返しになる作業を楽にできる様にVBAも触ってみたい。