Windows11での自動化はPowerShell(PS)ではなくても出来るが、PSで出来ておいたほうが良いんじゃないか・・・いや、存在する以上出来ないとなんか気持ち悪いじゃないか、などと思ってしまい、人生で初めて覚えてみた。
通常のプログラミング言語やスクリプトと比べて癖の強さは知っていたので敬遠していたが、触ってみると割りと使えるなぁ・・・などと思っていたらやはり変態だった。
[regex]::matchの戻り値の型はSystem.Text.RegularExpressions.Matchであり、Match::valueというメンバを持ち、これを関数の戻り値にした場合にSystem.Object[]などというObjectの配列として帰ってくる。
この型の扱いがよくわからんので、この配列をノリで[int32]にキャストして返してみたところSystem::ObjectとSystem::Int32の配列として帰ってくる。どうやらいろんな情報の配列としてマッチ結果を扱うらしい。
この場合戻り値を$resという変数に入れたとすると、System::Int32という型の目的の値は配列の2番目の要素に入っているので、$res[1]などとアクセスする。絶対正当じゃないしもっと普通のやり方があるはずなのだが検索するのがとても怠い。なんか直感的に使えねぇ・・・
また、ファイル名に半角角括弧([、])が含まれている場合、コマンドやコマンドレットに-literalpathオプションを付けてパスを指定しないとエラーになる。
きんもちわりぃぃぃ
PS1ファイルと同じディレクトリにあるTSファイルをMP4にエンコして適当なディレクトリに出力するスクリプト。きっと色々変なのだろう。
function enc_ts(){ Set-Location "\\192.168.1.10\conv" Get-Location $items = gci -filter .\*.ts -file foreach($item in $items){ $mp4 = [regex]::Replace( ".\tmp\" + [system.io.path]::GetFileNameWithoutExtension($item) + ".mp4" , "\d{18}-" , "" ) $mp4 = [regex]::Replace($mp4, "\[", "(") $mp4 = [regex]::Replace($mp4, "\]", ")") .\ffmpeg.exe -y ` -i $item -c:v libx265 -preset veryfast -crf 26 -s 1280x720 -map 0:v ` -c:a copy -map 0:a ` -filter:v bwdif=mode=send_field:parity=auto:deint=all ` $mp4 del -LiteralPath $item } } enc_ts # main function
色々きもいなぁとかいいつつも、ファイル操作や文字列置換ぐらいは特に変な仕様にぶつかることもなく手軽に行えるので便利だ。
高度なインフラでリモート操作等を行いたい等の意図は仕様からわかる。
また、別プロセスを実行したときの標準出力と標準エラー出力も手軽に扱えるというところも良い。
リモートPCに対して操作を行っているとつい混同してしまうのだが、スクリプト上で普通のコマンドとして実行された実行ファイルは、スクリプトを実行したPCのリソースを使って処理を行う。リモートPC上でプロセスを作成する機能もPowerShellには用意されているようだが、それとは異なる。
まぁでも、こんなんならC++からやるわ