2024年3月
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29    
無料ブログはココログ

 

« 株:現物売り約定(日立化成、アサヒホールディングス、旭ダイアモンド工業、DMG森精機、MARUWA、OBARA GROUP、KADOKAWA・DOWANGO)未単元株買い約定:(KADOKAWA・DOWANGO) | トップページ | 今週届いた本 »

2015年8月21日 (金)

PowerShell スクリプトでパイプから値を取得する方法

PowerShell スクリプトでパイプから値を取得する方法を試行錯誤してみた。
Cmdletは引数の定義で Parameter(ValueFromPipeline=$True) とすれば、パイプの値を取得できる。
スクリプトも同様に引数の定義を設定でき、パイプ以外の引数はちゃんと処理されるのだが、パイプを受け取る変数をそのまま参照すると、最後の値しか参照できない。
パイプの値は、$input に設定されるので、これを参照するというのがFinal Answer.引数定義と併用できるので、メンドクサイ引数チェックは[CmdletBinding()]で定義すればよろし。

  • 引数定義でパイプからも取得できるように設定できる。
    [CmdletBinding()]param(Parameter(ValueFromPipeline=$True)[String[]]$test]
    でも、$testをそのまま参照しても、最後の値しか参照できない。
  • 引数定義のパイプの値は、processブロック内で引数変数を参照すれば、全ての値を参照できることが分かった。でも、functionを定義するとシンタックスエラーになる。
    全ての処理をベタに書けと?
  • processブロックを&{ }の中に書けば、functionを定義できる。
    でも、パイプの最後の値しか参照できない!どないせいっちゅーんや!!
  • パイプの値は、$input に格納される。これを使えばよい。
    でも、スクリプト中にパイプを使うと$inputの内容は破棄される。
    一時変数に内容をコピーすればOK。コピーは、@($input)。
    $inputをそのまま一時変数に代入すると、参照渡しになるので、$inputが破棄されたら一時変数の内容も破棄される。

以下、スクリプトでの試行錯誤の結果。

●$input を使用した方法

PS > get-content ./test1.ps1
#$input に パイプの値が入る。関数内で$inputの内容をパイプで処理すると、中身が消える。\(>Д<)/
#なので、一時変数にコピーを取る。代入だと参照渡しになるので、一時変数の内容も一緒に消える。\(>Д<)/
$tmp = @($input)
$tmp | %{ Write-Output $_ }

Write-Output "Argment `$input=[${tmp}]"

PS > 1..2 | ./test1.ps1
1
2
Argment $input=[1 2]

●NGケース1:引数定義で取得

PS > get-content ./test2.ps1
[CmdletBinding()]
param(
        [Parameter(ValueFromPipeline=$True,Mandatory=$True)]
        [String[]]$test
)

$test | %{ Write-Output $_ }

Write-Output "Argment `$test=[${test}]"

PS > 1..2 | ./test2.ps1
2
Argment $test=[2]

●OK?ケース:引数定義で取得:processブロックで参照

PS > get-content ./test3.ps1
[CmdletBinding()]
param(
        [Parameter(ValueFromPipeline=$True,Mandatory=$True)]
        [String[]]$test
)


begin{
        $test | %{ Write-Output $_ }

        Write-Output "begin Argment `$test=[${test}]"
}
process{
        $test | %{ Write-Output $_ }

        Write-Output "process Argment `$test=[${test}]"
}
end{
        $test | %{ Write-Output $_ }

        Write-Output "end Argment `$test=[${test}]"
}

PS > 1..2 | ./test3.ps1
begin Argment $test=[]
1
process Argment $test=[1]
2
process Argment $test=[2]
2
end Argment $test=[2]

●NGケース:引数定義で取得:関数定義のため&{ }の中でprocessブロックを定義

PS > get-content ./test3_1.ps1
[CmdletBinding()]
param(
        [Parameter(ValueFromPipeline=$True,Mandatory=$True)]
        [String[]]$test
)

function test() {
        Write-Output "func-test"
}
&{
        begin{
                $test | %{ Write-Output $_ }

                Write-Output "begin Argment `$test=[${test}]"
        }
        process{
                $test | %{ Write-Output $_ }

                Write-Output "process Argment `$test=[${test}]"
                test

        }
        end{
                $test | %{ Write-Output $_ }

                Write-Output "end Argment `$test=[${test}]"
        }
}

PS > 1..2 | ./test3_1.ps1
2
begin Argment $test=[2]
2
process Argment $test=[2]
func-test
2
end Argment $test=[2]


●OKケース:引数定義と$inputで取得:関数定義のため&{ }の中でprocessブロックを定義:いらないケド

PS > get-content .\test3_2.ps1
[CmdletBinding()]
param(
        [Parameter(ValueFromPipeline=$True,Mandatory=$True)]
        [String[]]$test
)

function func-test() {
        Write-Output "func-test"
}
$tmp = @(${input})
&{
        begin{

                $test | %{ Write-Output "begin:test $_ " }
                $tmp | %{ Write-Output "begin:input $_ " }

                Write-Output "begin Argment `$test=[${test}], `$input=[${tmp}]"
        }
        process{

                $test | %{ Write-Output "process:test $_ " }
                $tmp | %{ Write-Output "process:input $_ " }

                Write-Output "process Argment `$test=[${test}], `$input=[${tmp}]"
                func-test

        }
        end{

                $test | %{ Write-Output "end:test $_ " }
                $tmp | %{ Write-Output "end:input $_ " }

                Write-Output "end Argment `$test=[${test}], `$input=[${tmp}]"
        }
}

PS > 1..2 | .\test3_2.ps1
begin:test 2
begin:input 1
begin:input 2
begin Argment $test=[2], $input=[1 2]
process:test 2
process:input 1
process:input 2
process Argment $test=[2], $input=[1 2]
func-test
end:test 2
end:input 1
end:input 2
end Argment $test=[2], $input=[1 2]

« 株:現物売り約定(日立化成、アサヒホールディングス、旭ダイアモンド工業、DMG森精機、MARUWA、OBARA GROUP、KADOKAWA・DOWANGO)未単元株買い約定:(KADOKAWA・DOWANGO) | トップページ | 今週届いた本 »

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: PowerShell スクリプトでパイプから値を取得する方法:

« 株:現物売り約定(日立化成、アサヒホールディングス、旭ダイアモンド工業、DMG森精機、MARUWA、OBARA GROUP、KADOKAWA・DOWANGO)未単元株買い約定:(KADOKAWA・DOWANGO) | トップページ | 今週届いた本 »