質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

Q&A

1回答

11310閲覧

PowerShellで取り込んだCSVのパティング後のマッチング・文字列置換処理について

MMMZ

総合スコア8

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

0グッド

0クリップ

投稿2016/08/03 09:07

編集2016/08/03 09:26

###前提・実現したいこと
PowerShell(ver0.2)で、2つのcsvファイルを読み込み特定の列の値に対しそれぞれゼロ埋めとNULLの数値化を行い、その後、成型した値でマッチングを行い数値を文字列に置き換えてCSVファイルを出力するスクリプトを作っています。

・データ成型したい値の情報
値は1桁~3桁まであるので、すべて3桁にしたい
ex: 1 ⇒001 、10⇒010
※NULLの場合がある

<今問題なこと>

ゼロ埋め処理がうまく引き継がれていないのか、
その後のマッチング~置換・出力の前処理で下記のような結果になってしましいます。

もともと3桁の値 ⇒置換処理される
もともと1桁、2桁およびNULLの値 ⇒置換処理されない

どう組めばエラーなく、該当する全ての値を置換できるようになるかご教示ください。

###発生している問題・エラーメッセージ

null 値の式ではメソッドを呼び出せません。 発生場所 行:6 文字:19 + %{ $_.END.PadLeft <<<< (3,"0")} + CategoryInfo : InvalidOperation: (PadLeft:String) []、RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull インデックスの演算が失敗しました。配列のインデックスが null に評価されました。 発生場所 行:14 文字:19 + %{$_.ID2 = $dic[ <<<< $_.ID2] ; $_} | + CategoryInfo : InvalidOperation: (:) []、RuntimeException + FullyQualifiedErrorId : NullArrayIndex

###該当のソースコード

Windows

1 2 3Get-Content C:\work\INPUT_LIST.csv | ConvertFrom-Csv -Header ID,NAME,IP,HOST,HOST2 | 4 %{ $_.ID.PadLeft(3,"0")} 5 6Get-Content C:\work\INPUT.csv | ConvertFrom-Csv -Header No.,day,ID1,ID2 | 7 %{ $_.ID1.PadLeft(3,"0")} | 8 %{ $_.ID2.PadLeft(3,"0")} 9 10 $dic = @{} 11Get-Content C:\work\INPUT_LIST.csv | ConvertFrom-Csv -Header ID,NAME,IP,HOST,HOST2 | 12 %{$dic[$_.ID] = $_.NAME} 13 14Get-Content C:\work\INPUT.csv | ConvertFrom-Csv -Header No.,day,ID1,ID2 | 15 %{$_.ID1 = $dic[$_.ID1] ; $_} | 16 %{$_.ID2 = $dic[$_.ID2] ; $_} | 17 Export-Csv C:\work\data\OUTPUTData.csv -encoding Default

###試したこと
ネットで調べましたが開発経験が浅く解決に至りませんでした。
事前処理結果をテンポラリに格納して、置換処理時に参照するような処理が必要なのでしょうか。

###補足情報(言語/FW/ツール等のバージョンなど)
バージョン:2.0
実行環境:Winsows 7

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

START と END はどこから出てきましたか?

PowerShell

1Get-Content C:\work\INPUT.csv | ConvertFrom-Csv -Header No.,day,ID1,ID2 | 2 %{ $_.START.PadLeft(3,"0")} | 3 %{ $_.END.PadLeft(3,"0")}

###追記
たとえばこれを

PowerShell

1Get-Content C:\work\INPUT.csv | ConvertFrom-Csv -Header No.,day,ID1,ID2 | 2 %{ $_.ID1.PadLeft(3,"0")} | 3 %{ $_.ID2.PadLeft(3,"0")}

こう変えるとお望みの動作になりますか?

PowerShell

1Get-Content C:\work\INPUT.csv | ConvertFrom-Csv -Header No.,day,ID1,ID2 | 2 Select-Object No., day, @{Name="ID1"; Expression={$_.ID1.PadLeft(3, "0")}}, @{Name="ID2"; Expression={$_.ID2.PadLeft(3, "0")}}

###追記
これで試してみてください。

input.csv

CSV

11601,2016/08/04,001,001 21017,2016/08/04,002,025 31058,2016/08/04,103,001 41358,2016/08/04,500,002 50910,2016/08/04,500,""

input_list.csv

CSV

1001,りんご支店 2002,バナナ支店 3025,キウイ支店 4103,みかん支店 5500,メロン支店

convert.ps1

PowerShell

1$dic = @{} 2Import-Csv .\input_list.csv -Header ID, Name | 3 % {$dic[$_.ID] = $_.Name} 4Import-Csv .\input.csv -Header No., day, ID1, ID2 | 5 Select-Object No., day, @{Name="ID1"; Expression={$dic[$_.ID1.PadLeft(3, "0")]}}, @{Name="ID2"; Expression={$dic[$_.ID2.PadLeft(3, "0")]}} | 6 Export-Csv .\OUTPUTData.csv -Encoding Default -NoTypeInformation -Force

投稿2016/08/03 09:15

編集2016/08/04 14:08
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MMMZ

2016/08/03 09:29

投稿用に項目名に変えたつもりが、漏れていたようです。失礼しました。 START→ID1 END→ID2
Zuishin

2016/08/03 09:42

CSV のデータが無いところは null ではなく "" となります。 ここで null が出てくるのは、ID1 のデータに対して ID2 を求めているからです。 つまり %{ $_.ID1.PadLeft(3,"0")} によって ID1 のデータが抽出されます。その抽出されたデータに対して %{ $_.ID2.PadLeft(3,"0")} を行っています。ID1 には ID2 というプロパティはありませんので、その結果は null になります。 null に対して PadLeft() を呼ぼうとしているので、例外が発生しています。
MMMZ

2016/08/04 02:18

ありがとうございます。 Windows PowerShell ISE上で修正結果を実施したところ、パティング処理はうまく実行されているようでした。 ただ、後続の置換処理の際に以下のエラー文が複数表示されました。 インデックスの演算が失敗しました。配列のインデックスが null に評価されました。 また、出力結果を参照したところ、置換処理も前処理でパティングした項目はできておりませんでした。エラーは先にご説明いただいたような内容と同じかと推測するのですが、、、 発生場所 行:13 文字:19 + %{$_.ID2 = $dic[ <<<< $_.ID2] ; $_} | + CategoryInfo : InvalidOperation: (:) []、RuntimeException + FullyQualifiedErrorId : NullArrayIndex <エラー箇所> Get-Content C:\work\INPUT.csv | ConvertFrom-Csv -Header No.,day,ID1,ID2 | %{$_.ID1 = $dic[$_.ID1] ; $_} | %{$_.ID2 = $dic[$_.ID2] ; $_} | 以下のように修正し、実施したところ、 ID1、ID2に該当するカラムに他の項目の参照情報も付与された状態の長いデータに置換されて出力されていました。(エラーはなかったです。) Get-Content C:\work\basyohenkan2\dakokubasyo.csv | ConvertFrom-Csv -Header No.,day,ID1,ID2 | Select-Object No., day, @{Name="ID1"; Expression={$_.ID1 = $dic[$_.ID1] ; $_}}, @{Name="ID2"; Expression={$_.ID2 = $dic[$_.ID2] ; $_}} |
MMMZ

2016/08/04 02:20

エラー文が抜けておりました。 <エラー文> インデックスの演算が失敗しました。配列のインデックスが null に評価されました。 発生場所 行:13 文字:19 + %{$_.ID2 = $dic[ <<<< $_.ID2] ; $_} | + CategoryInfo : InvalidOperation: (:) []、RuntimeException + FullyQualifiedErrorId : NullArrayIndex
Zuishin

2016/08/04 02:57

どういうデータを加工してどういう出力を得たいと思っておられるのかがわからないので、とりあえず一つだけ直しました。 後はその応用で直せると思ったのですが、ID1 と ID2 のみ必要で他のカラムは不要と言う意味でしょうか? もしそうであれば Select-Object の引数を減らすことで対応できます。
MMMZ

2016/08/04 05:43

入退室管理を目的に、支店コードと支店名が記載されたリスト(INPUT_LIST.csv)をもとに、当日の入退室情報ログ(INPUT.csv)に出力された当日の入室時、退室時の拠点コード(ID1、ID2)を支店名(NAME)に置換したデータ(OUTPUTData.csv)を生成したいと考えております。 ・変換前ファイル 社員番号,年月日,入室支店コード,最終退室支店コード 1601,2016/08/04,001,001,~ 1017,2016/08/04,002,025,~ 1058,2016/08/04,103,001,~ 1358,2016/08/04,500,002,~ 0910,2016/08/04,500,"",~ ~ ・変換後ファイル(最終的に出力したい形式) 社員番号,年月日,入室支店名,最終退室支店名 1601,2016/08/04,りんご支店,りんご支店,~ 1017,2016/08/04,バナナ支店,キウイ支店,~ 1058,2016/08/04,みかん支店,りんご支店,~ 1358,2016/08/04,メロン支店,バナナ支店,~ 0910,2016/08/04,メロン支店,"",~ ~ >>後はその応用で直せると思ったのですが、ID1 と ID2 のみ必要で他のカラムは不要と>>言う意味でしょうか? カラムに関しては、上記の通り、No.,day,ID1,ID2で形成したいです。 ⇒(社員番号,年月日,入室支店名,最終退室支店名) 文章がわかりずらく申し訳ございませんが、 現在だと、3カラム目と4カラム目に下記のような値が代入されてしまいます。 ⇒@{No.=社員番号; day=年月日; START=コードから置換した支店名; END=コードから置換した支店名} ここ2.3日でPowerShellに取り組み始めたため応用が難しく、恐縮ですがお知恵をお貸しいただければと思います。
Zuishin

2016/08/04 14:10

追記しました。input.csv および input_list.csv のエンコードが UTF8 でない場合、Import-CSV のオプションで -Encoding を指定してください。
MMMZ

2016/08/05 02:58

ありがとうございます。 いただいたソースで実行すると、 ・支店コードが1桁と2桁のものは置換できませんでした ・置換結果処理されたカラムの文字化けしていました。 こちらは調べたところ、当方の環境がver02なので、Import-CSVでのEncodingに対応していないのが原因のようです。
Zuishin

2016/08/05 05:52

そう言えば version 2.0 でしたね? こちらも 2.0 で試してみましたが、確かに Shift_JIS のものが文字化けしました。 Import-Csv を、ご自分でされていたように Get-Content | ConvertForm-Csv にすれば文字化けしないことを確認しました。 支店コードが 1 桁や 2 桁というのはどういうことでしょうか? input.csv の支店コードを 3 桁未満にしてみましたが、間違いなく動作しました。 input_list.csv のことであれば、それは PadLeft を使っている以上当然の動作です。 省略をこちらで補完しなければならないものではなく、私の挙げたように、実際に使えるデータとスクリプトを挙げてみてください。
Zuishin

2016/08/18 22:29

どうなりましたか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問