Làm cách nào để tôi chỉ nhận được các thư mục bằng Get-ChildItem?


242

Tôi đang sử dụng PowerShell 2.0 và tôi muốn loại bỏ tất cả các thư mục con của một đường dẫn nhất định. Lệnh sau xuất ra tất cả các tệp và thư mục, nhưng tôi không thể tìm ra cách lọc các tệp.

Get-ChildItem c:\mypath -Recurse

Tôi đã thử sử dụng $_.Attributesđể có được các thuộc tính nhưng sau đó tôi không biết cách xây dựng một thể hiện theo nghĩa đen System.IO.FileAttributesđể so sánh nó với. Trong cmd.exeđó sẽ là

dir /b /ad /s

Câu trả lời:


292

Đối với các phiên bản PowerShell dưới 3.0:

Đối FileInfotượng được trả về Get-ChildItemcó thuộc tính "cơ sở" , PSIsContainer. Bạn muốn chỉ chọn những mục đó.

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }

Nếu bạn muốn tên chuỗi thô của các thư mục, bạn có thể làm

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

Đối với PowerShell 3.0 trở lên:

dir -Directory

20
Mong muốn đó được đặt bí danh là "IsFolder".
xcud

5
xcud: Không phải mọi cấu trúc phân cấp được đại diện bởi PSDrive đều dựa trên thư mục.
Joey

10
Khoảng cách ngữ nghĩa giữa "container" và "thư mục" không phải là khoảng cách bạn có thể lái xe tải đi qua.
xcud

5
@xcud: Xem câu trả lời của iraSenthil. -Directory và -File cũng hoạt động trên Get-ChildItem. Không cần sử dụng thuộc tính PSIsContainer trực tiếp.
Wouter

(Get-ChildItem |? {$ _. PSIsContainer} | Chọn Tên) .Tên
Jose Ortega

195

Trong PowerShell 3.0, nó đơn giản hơn:

Get-ChildItem -Directory #List only directories
Get-ChildItem -File #List only files

33
dir là bí danh của Get-ChildItem
Chip McCormick

1
@crashmstr Bạn có chắc không? Tôi đã kiểm tra trên PS4.0 của tôi. Đối với tôi, dirđược lấy bí danh là Get-ChildItem, và -Directory-Filelựa chọn làm việc như mô tả. Tôi đã sử dụng các lệnh echo $PSVersionTable, help dir, dir -Directorydir -Fileđể đưa ra nhận xét này.
Peter Hull

3
Đây phải là câu trả lời
Chris S

2
lsdirlà bí danh của Get-ChildItemchất độc của bạn
Kolob Canyon

53

Sử dụng

Get-ChildItem -dir #lists only directories
Get-ChildItem -file #lists only files

Nếu bạn thích bí danh, sử dụng

ls -dir #lists only directories
ls -file #lists only files

hoặc là

dir -dir #lists only directories
dir -file #lists only files

Để tái diễn các thư mục con là tốt, thêm -rtùy chọn.

ls -dir -r #lists only directories recursively
ls -file -r #lists only files recursively 

Đã thử nghiệm trên PowerShell 4.0, PowerShell 5.0 (Windows 10), PowerShell Core 6.0 (Windows 10, Mac và Linux) và PowerShell 7.0 (Windows 10, Mac và Linux).

Lưu ý : Trên PowerShell Core, symlink không được theo dõi khi bạn chỉ định công -rtắc. Để theo liên kết tượng trưng, ​​chỉ định -FollowSymlinkchuyển đổi với -r.

Lưu ý 2 : PowerShell hiện là đa nền tảng, kể từ phiên bản 6.0. Phiên bản đa nền tảng ban đầu được gọi là PowerShell Core, nhưng từ "Core" đã bị loại bỏ kể từ PowerShell 7.0+.

Tài liệu Get-ChildItem: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.man quản lý / get-childitem


2
Điều này sẽ không hoạt động trong Powershell 2.0, đây là nhu cầu cụ thể của OP. - [/ Dir / Directory] không phải là tham số hợp lệ trong Powershell 2.0
Ben Personick

21

Một cách tiếp cận sạch hơn:

Get-ChildItem "<name_of_directory>" | where {$_.Attributes -match'Directory'}

Tôi tự hỏi nếu PowerShell 3.0 có một công tắc chỉ trả về các thư mục; nó có vẻ như là một điều hợp lý để thêm


1
FYI powershell 3.0 thêm -Directory-Filecờ
WickyNilliams


6

Từ PowerShell v2 và mới hơn (k đại diện cho thư mục bạn đang bắt đầu tìm kiếm tại):

Get-ChildItem $Path -attributes D -Recurse

Nếu bạn chỉ muốn tên thư mục mà không có gì khác, hãy sử dụng cái này:

Get-ChildItem $Path -Name -attributes D -Recurse

Nếu bạn đang tìm kiếm một thư mục cụ thể, bạn có thể sử dụng như sau. Trong trường hợp này, tôi đang tìm một thư mục có tên myFolder:

Get-ChildItem $Path -attributes D -Recurse -include "myFolder"

Và sử dụng PS 3.0 o 4.0?
Kiquenet

5
Tham số thuộc tính dường như không có trong PS2, nó báo lỗi "Không thể tìm thấy tham số khớp với tên tham số 'Thuộc tính'". Nó hoạt động tốt trong PS3.
WileCau

5

Ít văn bản được yêu cầu với phương pháp này:

ls -r | ? {$_.mode -match "d"}

Đây là cái tôi sẽ sử dụng.
David Betz

2
Thậm chí ngắn hơn: ls -r | ? {$ _. mode -match "d"}
jyggorath

Điều này không tìm thấy các thư mục nén
Charles Lambert

7
Bởi vì một thư mục nén là một tệp zip
user1594322 5/2/2015

Nó không phải luôn luôn hữu ích để tái diễn tất cả mọi thứ. Bạn có thể có một cây cực kỳ sâu và rậm rạp, nơi bạn chỉ quan tâm đến các thư mục chính xác xuống hai cấp; tìm kiếm ba mươi cấp xuống là một sự lãng phí thời gian.
Ross Presser

4

Sử dụng:

dir -Directory -Recurse | Select FullName

Điều này sẽ cung cấp cho bạn một đầu ra của cấu trúc gốc với tên thư mục chỉ dành cho thư mục.


3

Sử dụng:

Get-ChildItem \\myserver\myshare\myshare\ -Directory | Select-Object -Property name |  convertto-csv -NoTypeInformation  | Out-File c:\temp\mydirectorylist.csv

Cái nào sau đây

  • Lấy danh sách các thư mục ở vị trí đích: Get-ChildItem \\myserver\myshare\myshare\ -Directory
  • Chỉ trích xuất tên của các thư mục: Select-Object -Property name
  • Chuyển đổi đầu ra sang định dạng CSV: convertto-csv -NoTypeInformation
  • Lưu kết quả vào một tệp: Out-File c:\temp\mydirectorylist.csv

2
Sẽ thật tuyệt nếu bạn có thể giải thích từng bước để nhiều người có thể thấy những gì đang diễn ra.
jazzurro

Điều này sẽ không hoạt động trong Powershell 2.0, đây là nhu cầu cụ thể của OP. - [/ Dir / Directory] không phải là tham số hợp lệ trong Powershell 2.0
Ben Personick

2

Một cách tiếp cận đơn giản và dễ đọc hơn có thể đạt được với kịch bản dưới đây:

$Directory = "./"
Get-ChildItem $Directory -Recurse | % {
    if ($_.Attributes -eq "Directory") {
        Write-Host $_.FullName
    }
}

Hi vọng điêu nay co ich!


2

Bạn sẽ muốn sử dụng Get-ChildItem để nhận đệ quy tất cả các thư mục và tệp trước tiên. Và sau đó chuyển đầu ra thành mệnh đề Where-Object chỉ lấy các tệp.

# one of several ways to identify a file is using GetType() which
# will return "FileInfo" or "DirectoryInfo"
$files = Get-ChildItem E:\ -Recurse | Where-Object {$_.GetType().Name -eq "FileInfo"} ;

foreach ($file in $files) {
  echo $file.FullName ;
}

1

Câu trả lời được chấp nhận đề cập

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

để có được một "chuỗi thô". Nhưng trong thực tế các đối tượng của loại Selected.System.IO.DirectoryInfosẽ được trả lại. Đối với chuỗi thô có thể được sử dụng như sau:

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | % { $_.FullName }

Sự khác biệt quan trọng nếu giá trị được nối với một chuỗi:

  • với sự Select-Objectngạc nhiênfoo\@{FullName=bar}
  • với người ForEachđiều hành dự kiến:foo\bar

1
Chọn-Object sẽ thực sự trả về các đối tượng thuộc loại PSCustomObject. Mặc dù bạn có thể sử dụng% (là ForEach-Object) để lấy các chuỗi thô như bạn đã làm, bạn cũng có thể sử dụngSelect-Object -ExpandProperty FullName
JamesQMurphy


0

Sử dụng cái này:

Get-ChildItem -Path \\server\share\folder\ -Recurse -Force | where {$_.Attributes -like '*Directory*'} | Export-Csv -Path C:\Temp\Export.csv -Encoding "Unicode" -Delimiter ";"

0

Để trả lời câu hỏi ban đầu cụ thể (sử dụng IO.FileAttribut):

Get-ChildItem c:\mypath -Recurse | Where-Object {$_.Attributes -and [IO.FileAttributes]::Directory}

Tôi thích giải pháp của Marek hơn ( Where-Object { $_ -is [System.IO.DirectoryInfo] }).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.