LoginSignup
1
0

More than 1 year has passed since last update.

powershellスクリプトでテキストファイルを文字列置換

Last updated at Posted at 2021-05-20

表題の通り。powershellを全く触ったことがない人向け。

powershellの文字列置換を使って、テンプレートファイルのYYYY/MM/DDを書き換えることを目指す。

初めてpowershellスクリプトを触って、詰まったことをメモ。

始める前に

powershellスクリプトは*.ps1の形式で保存する。

【重要】スクリプトの実行ができるようにポリシーを変更しておく。詳細は以下。

https://qiita.com/opengl-8080/items/bb0f5e4f1c7ce045cc57

標準入力 -> 置換 -> 標準出力

単に文字列を置換したい場合は、次のように書く。

simpleReplace.ps1
$a = "abc"
$b = $a -replace "a","A"
Write-Output $b

実行すると、確かにa->Aになっていることがわかる。

console
> .\simpleReplace.ps1 

Abc

あるいは、標準入力の一部を置換して標準出力に出したい場合は、以下のように書く。

simpleReplaceWithArgs.ps1
Param([String]$a)
$b = $a -replace "a","A"
Write-Output $b
console
> .\simpleReplaceWithArgs.ps1 abc

Abc

余談だが、Write-Outputechoと書いてもよい。言い換えれば、echoWrite-Outputのエイリアスとして設定されている。

また、powershellでは、変数の大文字小文字を区別しないことも知られている。

従って、次のコードでも同様に動作する。

simpleReplaceWithArgs2.ps1
Param([String]$a)
$b = $a -replace "a","A"
echo $B #echoはWrite-Outputのエイリアス、$Bは$bと同じ

テキストファイル -> 置換 -> テキストファイル

上から少し発展して、

  1. テキストファイルから文字列を読み込んで、
  2. 一行ずつ文字列置換の判定を行い、
  3. 新しいテキストファイルに出力する

ことを考える。

要件として、

  • 引数を年 月 日の形で与える。(例 : 2021 05 21)
  • template.txtから文字列を読み込む
  • 文字列中のYYYY, MM, DDを引数で与えた日付に置き換える
  • 書き出し先のファイル名は引数で指定した[年月日].txtとする(例 : 20210521.txt)
  • すでに同名のファイルがある場合は何もしない

コードと実行結果は以下。

template.txt
今日はYYYY年MM月DD日です
create_report.ps1
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
20210507.txt
今日は2021年05月07日です

日付が正しく書き換えられたことがわかる。

以下、はまったことに関するメモ。

  • 引数の型

    引数を指定する際、単にParam($mm)とすると、powershellが勝手にキャスティングを行ってしまう(05 -> 5など)。これを防ぐために、Param([String]$mm)と書いてあらかじめ型を指定しておく。

  • エンコーディング

    特に日本語のファイルを読み書きするときは、Get-ContentOut-Fileの両方のオプションに-Encoding UTF8をつけておくべき。指定しないと、出力先のファイルのファイル形式がUTF16になるなど、とにかく予想できない動きをする。

  • 上書きの禁止

    Out-File -NoClobberにオプションをつけておくとファイルの上書きを禁止してくれる。次のサイトが良くまとまっている

    https://tech.guitarrapc.com/entry/2014/02/11/061627

  • 表記関係

    • ForEach-Objectのエイリアスとして%を使用可能
    • $_はパイプラインに渡されるオブジェクトを表す。
    • コマンド途中での改行はバッククォートを使う

まとめ

powershellの可能性を感じる。
将来的には、引数無しでpowershellから日付を取得するコードに書き換えたい。
->書き換えました(powershellスクリプトで日付取得してテキストファイルの日付を書き換え)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0