質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

Q&A

解決済

2回答

14304閲覧

PowerShell Get-ChildItemでサブディレクトリまで一括でファイル名を取得するとき、特定のディレクトリを対象から除外したい。

King_of_Flies

総合スコア382

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

0グッド

0クリップ

投稿2019/07/23 02:47

お疲れ様です。

以下のコードを実行すると、
フルパス+ファイル名称(tab)ファイルサイズという出力結果を得られますが、
これは実行するディレクトリ配下にあるファイルをすべて出力してしまいます。

Get-ChildItemには、-excludeというものが用意されており、
一致する文字列を持つファイルを出力対象から除外してくれるみたいなのですが、
ディレクトリに対しての、除外が出来ません。

PowerShwll

1Get-ChildItem $parent_folder -Recurse -file -exclude *Online* | Select-Object -Property Fullname,Length | Sort-Object Fullname | Foreach-Object { "$($_.FullName)`t$($_.Length)" }

(上記コマンドで得られる取得結果にhoge\hoge\Online\hoge.txtがある場合、Online配下のファイルを出力対象としないようにしたいのですが、
出力されてしまいます。

指定方法が誤っているのでしょうか。

皆様の知恵をお借りしたいです。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Get-ChildItem-Excludeパラメーターは、アイテムのパスではなく名前のみが対象だったと思うので、指定したディレクトリ以下を除外することはできません。

簡単な解決策はWhere-Objectを使ってアイテムのFullNameプロパティを対象にフィルタリングすることです。

PowerShell

1Get-ChildItem $parent_folder -File -Recurse | Where-Object FullName -NotLike *\Online*

追記:

もし指定フォルダのパスに除外フォルダと同名のフォルダが含まれている場合は以下のようにするとうまくいくかと思います。($parent_folderはフルパスだと仮定します。)

PowerShell

1Get-ChildItem $parent_folder -File -Recurse | Where-Object FullName -notlike "$parent_folder*\Online*"

この方法は一旦除外フォルダ以下のアイテムも全て拾った後にフィルタリングします。
よって、除外フォルダ以下に大量のファイルがある場合は、無駄な処理が多くなりパフォーマンスが悪くなることが欠点です。

効率よく指定フォルダ以下を除外するには再帰的にファイルを拾っていく処理を自分で書く必要があるかと思います。
以下は一例です。

PowerShell

1function lsx ([string]$Path = ".", [string[]]$ExcludeDir) { 2 3 $stack = [Collections.Generic.Stack[object]]::new(@($Path)) 4 $temp = [Collections.Generic.List[object]]::new() 5 $getChildItem = $ExecutionContext.InvokeProvider.ChildItem.Get 6 7 while ($stack.Count) { 8 $temp.Clear() 9 foreach ($item in $getChildItem.Invoke($stack.Pop(), $false, $false, $true)) { 10 if ($item.PSIsContainer) { if ($item.PSChildName -notin $ExcludeDir) { $temp.Add($item.PSPath) } } 11 else { $item } 12 } 13 foreach ($dir in $temp[($temp.Count - 1)..0]) { $stack.Push($dir) } 14 } 15}

使い方は以下です。

PowerShell

1lsx $parent_folder -Exclude "hoge","fuga"

この例では複数の除外フォルダ名を指定できます。ワイルドカード指定はできません。

投稿2019/07/23 08:19

編集2019/07/23 10:33
mitarai

総合スコア223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/07/23 08:44 編集

この一つ前の質問で同様な回答をしました。 失礼しました。他の質問者さんと間違えていました。上記は取り消します。
guest

0

-excludeオプションは取得結果から除外するパスを、それぞれ指定する。
との記載がありますので、パス指定してみてはいかがでしょう?

参考URL
https://www.atmarkit.co.jp/ait/articles/0808/22/news129.html

投稿2019/07/23 04:38

nanami12

総合スコア1015

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

King_of_Flies

2019/07/23 06:44

ここでいうパス指定は「*Online*」で実施しています。 フルパスで記載したらどうか?ということであれば、 実際の出力先のフォルダ階層は Hoge/*/Online/hoge.txtのように、 Onlineの上位階層のフォルダが複数存在し、それぞれの*配下にOnlineフォルダがある構造となっているため、フルパス指定でのexcludeの対応は不可能です。 すみません、後出しのような記載で。 以上です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問