1

セットアップ

次のようなフォルダー構造があります。

C:\RootFolder
            \file1.txt
            \file2.txt
            \license.txt
            \Settings
                     \fileA.txt
                     \fileB.txt
                     \settings.txt
            \OtherFolders

目標

license.txt と settings.txt 以外のすべてのファイルを削除します。

最終的には、次のものだけが残るようにしたいと思います。

  C:\RootFolder
                \license.txt
                \Settings
                         \settings.txt

遠くへのスクリプト

$exclude = @('license.txt', 'settings.txt')
Get-ChildItem C:\RootFolder -recurse -exclude $exclude | foreach ($_) {remove-item $_.fullname -recurse:$false}

問題

特に -recurse:$false を指定しても、「再帰が指定されていない」ことを示すメッセージが常に各フォルダーに生成され、すべての子アイテムが削除されるというメッセージが表示されます。

この後、license.txt ファイルは残りますが、settings.txt ファイル (サブディレクトリ内) は残りません。

4

2 に答える 2

3

投稿してすぐに答えが返ってきました。ディレクトリではなく、ファイルだけを探す必要がありました。

私は PowerShell 2.0 を使用しているため、powershell 3 で新しく追加された -File 属性を使用できませんでした。代わりに、すべてのオブジェクトをチェックして、それがコンテナーかどうかを確認する必要があります。

解決:

$exclude = @('license.txt', 'settings.txt')

Get-ChildItem C:\RootFolder -recurse -exclude $exclude | Where-Object {!($_.PSIsContainer)} | foreach ($_) {remove-item $_.fullname}

これは、私が必要としていたものを達成するために完全に機能しました。

ソリューションの改善

ここでのいくつかのコメント/投稿のおかげで、powershell についてもう少し教えてくれるエレガントな方法がいくつかあります。

  • Remove-Item は、パイプラインからコマンドを受け取ることができます。foreach は必要ありません。
  • Where-Object は「?」に短縮できます。
  • Get-ChildItem は "gci" (エイリアス) に短縮できます
  • Foreach の後に ($_) は必要ありません。Foreach はそれを自動的に理解します。
  • 除外を 1 行に配置したい場合は、配列をインラインで実行できます。

これらを考えると、ワンライナーに収まるエレガントなソリューションは次のようになります。

gci C:\RootFolder -Recurse -Exclude @('license.txt', 'settings.txt') | ? { ! $_.PSIsContainer } | Remove-Item -Force
于 2013-07-11T20:11:03.343 に答える