表題の通り。powershellを全く触ったことがない人向け。
powershellの文字列置換を使って、テンプレートファイルのYYYY/MM/DDを書き換えることを目指す。
初めてpowershellスクリプトを触って、詰まったことをメモ。
始める前に
powershellスクリプトは*.ps1
の形式で保存する。
【重要】スクリプトの実行ができるようにポリシーを変更しておく。詳細は以下。
https://qiita.com/opengl-8080/items/bb0f5e4f1c7ce045cc57
標準入力 -> 置換 -> 標準出力
単に文字列を置換したい場合は、次のように書く。
$a = "abc"
$b = $a -replace "a","A"
Write-Output $b
実行すると、確かにa->Aになっていることがわかる。
> .\simpleReplace.ps1
Abc
あるいは、標準入力の一部を置換して標準出力に出したい場合は、以下のように書く。
Param([String]$a)
$b = $a -replace "a","A"
Write-Output $b
> .\simpleReplaceWithArgs.ps1 abc
Abc
余談だが、Write-Output
はecho
と書いてもよい。言い換えれば、echo
はWrite-Output
のエイリアスとして設定されている。
また、powershellでは、変数の大文字小文字を区別しないことも知られている。
従って、次のコードでも同様に動作する。
Param([String]$a)
$b = $a -replace "a","A"
echo $B #echoはWrite-Outputのエイリアス、$Bは$bと同じ
テキストファイル -> 置換 -> テキストファイル
上から少し発展して、
- テキストファイルから文字列を読み込んで、
- 一行ずつ文字列置換の判定を行い、
- 新しいテキストファイルに出力する
ことを考える。
要件として、
- 引数を
年 月 日
の形で与える。(例 :2021 05 21
) - template.txtから文字列を読み込む
- 文字列中のYYYY, MM, DDを引数で与えた日付に置き換える
- 書き出し先のファイル名は引数で指定した
[年月日].txt
とする(例 :20210521.txt
) - すでに同名のファイルがある場合は何もしない
コードと実行結果は以下。
今日はYYYY年MM月DD日です
Param([String]$yyyy, [String]$mm, [String]$dd)
Get-Content -Encoding UTF8 ./template.txt `
| ForEach-Object {$_ -replace "YYYY", $yyyy} `
| ForEach-Object {$_ -replace "MM", $mm} `
| ForEach-Object {$_ -replace "DD", $dd} `
| Out-File -Encoding UTF8 $yyyy$mm$dd.txt -NoClobber
今日は2021年05月07日です
日付が正しく書き換えられたことがわかる。
以下、はまったことに関するメモ。
-
引数の型
引数を指定する際、単にParam($mm)
とすると、powershellが勝手にキャスティングを行ってしまう(05
->5
など)。これを防ぐために、Param([String]$mm)
と書いてあらかじめ型を指定しておく。 -
エンコーディング
特に日本語のファイルを読み書きするときは、Get-Content
とOut-File
の両方のオプションに-Encoding UTF8
をつけておくべき。指定しないと、出力先のファイルのファイル形式がUTF16になるなど、とにかく予想できない動きをする。 -
上書きの禁止
Out-File -NoClobber
にオプションをつけておくとファイルの上書きを禁止してくれる。次のサイトが良くまとまっている
https://tech.guitarrapc.com/entry/2014/02/11/061627 -
表記関係
-
ForEach-Object
のエイリアスとして%
を使用可能 -
$_
はパイプラインに渡されるオブジェクトを表す。 - コマンド途中での改行はバッククォートを使う
-
まとめ
powershellの可能性を感じる。
将来的には、引数無しでpowershellから日付を取得するコードに書き換えたい。
->書き換えました(powershellスクリプトで日付取得してテキストファイルの日付を書き換え)