treedown’s Report

システム管理者に巻き起こる様々な事象を読者の貴方へ報告するブログです。会社でも家庭でも"システム"に携わるすべての方の共感を目指しています。

※https化しました。その影響でしばらくリンク切れなどがあるかもしれませんが徐々に修正していきます。 リンク切れなどのお気づきの点がございましたらコメントなどでご指摘いただけますと助かります。

Powershellでファイル名から指定した文字列取っ払う

Powershellのお勉強の一環として、フォルダ内のファイルを一括で変更する、という課題を課して実行してみました。

今回実施したのは「特定フォルダ内のファイル名を一括変更する」中でも基本となる「特定の文字列を取り払う方法」のご報告です。

やること:ファイル名から文字列除去

今回実施するのは、前から手作業でやっていた
------------------------------------------------------

PS C:\Users\Public\UserLunch> dir


ディレクトリ: C:\Users\Public\UserLunch


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2018/05/30 17:03 1686 FFC.exe - ショートカット.lnk
-a--- 2018/05/30 17:03 1658 PCAsset.exe - ショートカット.lnk
-a--- 2018/05/30 17:03 1733 PGLST64.exe - ショートカット.lnk
-a--- 2018/05/30 17:04 1718 SKRWATCH.EXE - ショートカット.lnk
-a--- 2018/05/30 17:04 1718 SW_NORAS.EXE - ショートカット.lnk
-a--- 2018/05/30 17:04 1771 YbInfo.exe - ショートカット.lnk

------------------------------------------------------

いくつかのフリーソフトのショートカットを一つのフォルダにまとめて保管するのですが、
「.exe - ショートカット」
という文字列が.lnkファイル名に付属するので、これを手動で削除していました。
Powershellのお勉強も兼ねて、これを簡単に除去できることが判明(今更)。

結論:コマンド一行で可能

まず成功例の結論から、対象の場所にcdコマンドで移動し、

Get-ChildItem .\* | ForEach-Object { Rename-Item $_ -NewName ($_ -replace '.exe - ショートカット')}

で完了します。

Get-ChildItem %パス名%
で実行対象となるファイルの場所を指定します。
今回は事前にcdコマンドで対象のフォルダ(ディレクトリ)位置にカレントディレクトリを移動していたので、カレントディレクトリ配下のファイルすべてを意味する「.\*」を指定しました。
取得したファイル一覧をパイプシンボルで引き渡して、
Rename-Itemで名前を変更するように指定、さらにリネーム後の新しいファイル名を指定する条件として取り除く文字列である
'.exe - ショートカット'
を指定して処理は完了します。

あっさりと、
------------------------------------------------------
PS C:\Users\Public\UserLunch> dir


ディレクトリ: C:\Users\Public\UserLunch


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2018/05/30 17:03 1686 FFC.lnk
-a--- 2018/05/30 17:03 1658 PCAsset.lnk
-a--- 2018/05/30 17:03 1733 PGLST64.lnk
-a--- 2018/05/30 17:04 1718 SKRWATCH.lnk
-a--- 2018/05/30 17:04 1718 SW_NORAS.lnk
-a--- 2018/05/30 17:04 1771 YbInfo.lnk

------------------------------------------------------
成功しました。

最初は間違えていた例

最初は

Get-ChildItem .\* | ForEach-Object {Rename-Item $_ -Newname ( $_ -replase '.exe - ショートカット' ,'' )}

と実行していて

f:id:treedown:20180530175503p:plain


------------------------------------------------------
式またはステートメントのトークン '-replase' を使用できません。
発生場所 行:1 文字:75
+ Get-ChildItem .\* | ForEach-Object {Rename-Item $_ -Newname ( $_ -replase '.exe ...
+ ~~~~~~
式またはステートメントのトークン ''.exe - ショートカット'' を使用できません。
発生場所 行:1 文字:74
+ Get-ChildItem .\* | ForEach-Object {Rename-Item $_ -Newname ( $_ -replase '.exe ...
------------------------------------------------------
といった感じのエラーになっていました。
誤解したのは「$_ -replase '.exe - ショートカット' ,'' 」という部分。
「-replase」で指定する文字列を取っ払おうとしていたので、置換する-replaseの使い方を
「対象文字列をブランクと置換する」
ことによって、文字を取っ払うことが可能だ、と勘違いしていたのですが、
「-replase」は単純に取っ払うならそのまま単一の文字列を指定しておく、ということだったようです。

文字列置換するときは「-replase」に続けて二つ文字列を指定する、
文字列削除するときは「-replase」に続けて削除文字列だけ指定する、

という記述でやりたいことが実現可能でした。