Giới hạn độ sâu đệ quy Get-ChildItem


82

Tôi có thể lấy tất cả các mục con một cách đệ quy bằng lệnh này:

Get-ChildItem -recurse

Nhưng có cách nào để hạn chế độ sâu không? Nếu tôi chỉ muốn đệ quy một hoặc hai cấp độ xuống chẳng hạn?

Câu trả lời:


109

Sử dụng điều này để giới hạn độ sâu đến 2:

Get-ChildItem \*\*\*,\*\*,\*

Cách thức hoạt động là nó trả về các con ở mỗi độ sâu 2,1 và 0.


Giải trình:

Lệnh này

Get-ChildItem \*\*\*

trả về tất cả các mục có độ sâu bằng hai thư mục con. Thêm \ * sẽ thêm một thư mục con bổ sung để tìm kiếm.

Theo câu hỏi OP, để giới hạn tìm kiếm đệ quy bằng get-childitem, bạn bắt buộc phải chỉ định tất cả các độ sâu có thể được tìm kiếm.


Rất tuyệt vời. Tôi đoán là tôi chưa bao giờ cần làm điều này trong PowerShell, nhưng tôi biết tôi đã ước điều đó trước đây trong CMD.EXE.
aphoria

15
Có vẻ như bạn phải làm "-path \ * \ * \ *, \ * \ *, \ *" để kéo vào độ sâu trung gian.
Gerard ONeill

Tôi đã thử nó, nhưng nó dường như đi lên thay vì đi xuống. Làm cách nào để tôi có thể sử dụng nó để tạo Cây thư mục như trong superuser.com/questions/258287/… ? Cảm ơn bạn.
Royi

2
Để bắt đầu đệ quy từ thư mục hiện tại, một dấu chấm cần được thêm vào đầu mỗi đường dẫn. Get-ChildItem .\*\*\*,.\*\*,.\*Tại một số điểm, bởi PowerShell 5.1, Get-ChildItem bây giờ có một -Depththam số.
sáng

65

Kể từ powershell 5.0 , bây giờ bạn có thể sử dụng -Depththam số trong Get-ChildItem!

Bạn kết hợp nó với -Recurseđể hạn chế đệ quy.

Get-ChildItem -Recurse -Depth 2

4
Có vẻ như công -Recursetắc là tùy chọn / ngụ ý khi -Depthđược chỉ định.
Charlie Joynt

7
Một điều tôi thấy với điều này có vẻ kỳ lạ là -Excludekhi được bao gồm với giá trị -Depthphủ định -Depth.
ATek,

2
@ssaviers Vấn đề tương tự cũng xảy ra với -Include.
Eternal21

Đối với giá trị của nó, tham số -Depth dường như bị bỏ qua khi kết hợp với các ký tự đại diện. Ví dụ: gci c:\*.exe -Depth 1trả về tệp nhiều thư mục con sâu.
GuitarPicker

Tốt để biết! gci c:\ -filter *.exe -depth 1có thể sẽ giúp bạn có được thứ bạn muốn @GuitarPicker Tuy nhiên, tôi không có máy windows để kiểm tra ngay bây giờ
dee-see

9

Hãy thử chức năng này:

Function Get-ChildItemToDepth {
    Param(
        [String]$Path = $PWD,
        [String]$Filter = "*",
        [Byte]$ToDepth = 255,
        [Byte]$CurrentDepth = 0,
        [Switch]$DebugMode
    )

    $CurrentDepth++
    If ($DebugMode) {
        $DebugPreference = "Continue"
    }

    Get-ChildItem $Path | %{
        $_ | ?{ $_.Name -Like $Filter }

        If ($_.PsIsContainer) {
            If ($CurrentDepth -le $ToDepth) {

                # Callback to this function
                Get-ChildItemToDepth -Path $_.FullName -Filter $Filter `
                  -ToDepth $ToDepth -CurrentDepth $CurrentDepth
            }
            Else {
                Write-Debug $("Skipping GCI for Folder: $($_.FullName) " + `
                  "(Why: Current depth $CurrentDepth vs limit depth $ToDepth)")
            }
        }
    }
}

nguồn


1
Nó thực sự hoạt động. Lời gọi mẫu: Get-ChildItemToDepth -ToDepth 2(làm việc trên thư mục hiện tại)
Peter Mortensen

1

Tôi đã cố gắng giới hạn độ sâu đệ quy Get-ChildItem bằng cách sử dụng Resolve-Path

$PATH = "."
$folder = get-item $PATH 
$FolderFullName = $Folder.FullName
$PATHs = Resolve-Path $FolderFullName\*\*\*\
$Folders = $PATHs | get-item | where {$_.PsIsContainer}

Nhưng điều này hoạt động tốt:

gci "$PATH\*\*\*\*"

1

Đây là một hàm xuất ra một dòng cho mỗi mục, có thụt lề theo mức độ sâu. Nó có lẽ dễ đọc hơn nhiều.

function GetDirs($path = $pwd, [Byte]$ToDepth = 255, [Byte]$CurrentDepth = 0)
{
    $CurrentDepth++
    If ($CurrentDepth -le $ToDepth) {
        foreach ($item in Get-ChildItem $path)
        {
            if (Test-Path $item.FullName -PathType Container)
            {
                "." * $CurrentDepth + $item.FullName
                GetDirs $item.FullName -ToDepth $ToDepth -CurrentDepth $CurrentDepth
            }
        }
    }
}

Nó dựa trên một bài đăng trên blog, Practical PowerShell: Tỉa cây tệp và mở rộng Cmdlets .


0

@scanlegentil Tôi thích điều này.
Một chút cải tiến sẽ là:

$Depth = 2
$Path = "."

$Levels = "\*" * $Depth
$Folder = Get-Item $Path
$FolderFullName = $Folder.FullName
Resolve-Path $FolderFullName$Levels | Get-Item | ? {$_.PsIsContainer} | Write-Host

Như đã đề cập, điều này sẽ chỉ quét độ sâu được chỉ định, vì vậy sửa đổi này là một cải tiến:

$StartLevel = 1 # 0 = include base folder, 1 = sub-folders only, 2 = start at 2nd level
$Depth = 2      # How many levels deep to scan
$Path = "."     # starting path

For ($i=$StartLevel; $i -le $Depth; $i++) {
    $Levels = "\*" * $i
    (Resolve-Path $Path$Levels).ProviderPath | Get-Item | Where PsIsContainer |
    Select FullName
}

Điều này sẽ hiển thị tất cả các tên thư mục con để các quy định chiều sâu
kevro

1
Điều này dường như hiển thị các mục một độ sâu nhất định, chứ không phải lên đến một độ sâu nhất định.
sancho.s ReinstateMonicaCellio
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.