title:powershellの関数(function)の書き方 - プログラミング学習サイト

title:powershellの関数(function)の書き方

    6801883189108029690

前回までのお話はこちら

powershell 入門 学習サイト 〜繰り返し構文編〜

関数

関数の構文

function add_plus1 ($Number) {
    $Number++; 
    return $Number
}

関数の引数

#引数を撮る方法1: paramで指定

$num1 = 0 echo "num1 is $num1"
#2自分で関数を定義 
function add_plus1 { 
    param (
        $Number
    )
    $Number++;
    return $Number
}
$num2 = add_plus1($num1)
echo "num2 is $num2"

これは引数に対して1を加える簡単な関数

$Numberに与えられた数字は$Number++で一つだけ値が増える。

#引数を使う方法2:

function add_plus10 ($Number) {
    $Number++; 
    return $Number
}

関数名の横に(のなかで引数を指定することもできる)

#引数の型を指定することも可能

function add_plus10 ([int]$Number) {
    $Number++; 
    return $Number
}

引数の前に[]で型を指定することで、それ以外の型以外は代入できなくなる。

万が一以下のように文字列を指定して代入してしまったとしてもエラーが出る

add_plus10("アイウエオ")

このコードはエラーが出る

可変長引数

可変な長さの引数を取扱場合はargsを指定すればよい

function GetArgumentsFunction
{
    "First positional function argument is: " + $args[0]
    "Second positional function argument is: " + $args[1]
}
PS > GetArgumentsFunction One Two
Get-Arguments First 2
First named argument is: First

パイプライン入力にアクセスする

サンプルコード

function InputCounter {
    $count = 0
    ##  Go through each element in the pipeline, and add up
    ##  how many elements there were.
    foreach($element in $input){
        $count++ 
    }
    $count
}

実行例

ImportModule somefunction.pms1
dir $env:WINDIR | InputCounter
295

解説

$inputにはパイプラインからの入力が代入される。

多くのコマンドは配列として次のパイプラインが生成されるので受け取り手の関数を作る場合はforeachで回さなければいけない

begin process end

function InputCounter
{
    begin {
        $count = 0 
    }
    ##  Go through each element in the pipeline, and add up
    ##  how many elements there were.
    process {
        Write-Debug "Processing element $_"
        $count++ 
    }
    end {
        $count 
    }
}

関数内の記述はbegin process end の三段回に分けて書くことができる

この記述方法が大きな影響を及ぼすわけではないが、あなたのソリューションの意図を明確にできる。

以下のコードは同じ意味で機能的には差異がないが、どちらが見やすいだろうか

function Get-InputWithKeyword($identifier)
{
begin {
        Write-Host "Beginning InputWithKeyword (ID: $identifier)"
    }
process {
        Write-Host "Processing element $_ (ID: $identifier)"
$_ }
end {
        Write-Host "Ending InputWithKeyword (ID: $identifier)"
    }
}
function Get-InputWithForeach($identifier)
{
    Write-Host "Beginning InputWithForeach (ID: $identifier)"
    foreach($element in $input)
    {
        Write-Host "Processing element $element (ID: $identifier)"
$element }
    Write-Host "Ending InputWithForeach (ID: $identifier)"
}

例題):fizz buzzの判定部分を関数として独立させる

前回課題のfor文内のコードを関数として独立させよう

for ($i=1; $i -it 20; $i++) { if ($i % 15 -eq 0) {
echo "$i is fizzbuzz" } else if ($i % 5 -eq 0) {
echo "$i is buzz" Jelseif ($i % 3 -eq 0) {
echo "$i is fizz"

以下回答










回答例

function Judgement-Fizzbuzz($i){ 
    $answer = ""
    if ($i % 15 -eq 0) {
        $answer = "fizzbuzz" }
    else if ($i % 5 -eq 0) {
        $answer = "fizz" }
    else if ($i % 3 -eq 0) {
        $answer = "buzz" return $answer
    }
    return $answer
}
for ($i=1; $i -it 20; $i++) {
    $test = Judgement-Fizzbuzz($i)
    echo $test
}

パワーシェルの引数にスクリプトブロックを指定する

############################################################################## 
##  Map-Object.ps1
## 
##  Apply the given mapping command to each element of the input
## 
##  Example:
##     1,2,3 | Map-Object { $_ * 2 }
############################################################################## 
param([ScriptBlock] $mapCommand)
process {
    & $mapCommand
}

実行例

PS >1,2,3 | Map-Object { $_ * 2 }
2
4
6

PS >1,2,3 | Map-Object { ($_ + 2) * 3 }
9
12
15

PS >1,2,3 | Map-Object { ($_ + 3) * $_ }
4
10
18

解説

型[ScriptBlock]はその変数に{}で囲まれたpowershellコードを埋め込むことができる。

$_は与えられた引数全体を配列として捉えた時に、その一つ一つの値に同じ処理を施したい時に使う。

例えば

PS >1,2,3 | Map-Object { $_ * 2 }

の場合、1,2,3のそれぞれを表す$に対して 「$ * 2」つまり二倍するという処理を施している。

powershellの[ScriptBlock]で定義された$mapCommand変数にはこの{ $_ * 2 }が格納されており、

それをアンパサンド($)を使って実行できる。

参考記事

この記事は以下の書籍を参考に執筆されました。 詳しい内容の確認はこちらからお願いいたします。

title:powershellの関数を一分で解説する description:プログラミング言語powershellの入門サイトです。今回は第四弾、関数編 img:https://johobase.com/jb/wp-content/uploads/2021/03/taskbar-powershell-icon-contextmenu.png category_script:page_name.startswith("1")

page:https://minegishirei.hatenablog.com/entry/2024/05/21/120236