如何通过文件夹重复并显示相对文件夹路径?

发布于 2025-02-07 14:00:59 字数 1547 浏览 0 评论 0 原文

这是一个简单的脚本:

$srcpth = "C:\Users\Mark\Desktop\dummy\"
$files = Get-ChildItem -Path $srcpth -File -Recurse 

foreach ($f in $files) {
    $filen = $f.Name
    $filesize = $f.Length
    Write-Output "$filen $filesize"
    }

这将正确循环循环 c:\ users \ mark \ desktop \ dummy 和带有文件大小的输出文件名,但它不会显示相对路径。如何解决相对路径?谢谢。

编辑:下面添加以澄清所需的输出:

例如,在 c:\ users \ mark \ desktop \ dummy 下,是带有文件

C:\Users\Mark\Desktop\dummy\file00.txt
C:\Users\Mark\Desktop\dummy\folder01\file01_01.txt
C:\Users\Mark\Desktop\dummy\folder01\file01_02.txt
C:\Users\Mark\Desktop\dummy\folder01\file01_03.txt

C:\Users\Mark\Desktop\dummy\folder02\file02_01.txt
C:\Users\Mark\Desktop\dummy\folder02\file02_01.txt

C:\Users\Mark\Desktop\dummy\folder03\file03_01.txt
C:\Users\Mark\Desktop\dummy\folder03\file03_02.txt
C:\Users\Mark\Desktop\dummy\folder03\file03_03.txt
C:\Users\Mark\Desktop\dummy\folder03\file03_04.txt

输出的子文件夹,并产生上述代码:

file00.txt 9
file01_01.txt 10
file01_02.txt 12
file01_03.txt 12
file02_01.txt 15
file02_01.txt 14
file03_01.txt 11
file03_02.txt 15
file03_03.txt 13
file03_04.txt 12

但是我想要的是:

file00.txt 9
\folder01\file01_01.txt 10
\folder01\file01_02.txt 12
\folder01\file01_03.txt 12
\folder02\file02_01.txt 15
\folder02\file02_01.txt 14
\folder03\file03_01.txt 11
\folder03\file03_02.txt 15
\folder03\file03_03.txt 13
\folder03\file03_04.txt 12

先前的 \ ,no slash或。\ 很好。

Here is a simple script:

$srcpth = "C:\Users\Mark\Desktop\dummy\"
$files = Get-ChildItem -Path $srcpth -File -Recurse 

foreach ($f in $files) {
    $filen = $f.Name
    $filesize = $f.Length
    Write-Output "$filen $filesize"
    }

This will correctly loop through all subfolders in C:\Users\Mark\Desktop\dummy and output file name with file size, but it will not show relative path. How do I resolve the relative path? Thanks.

EDIT: added below for clarification of desired output:

For example, under C:\Users\Mark\Desktop\dummy are subfolders with files

C:\Users\Mark\Desktop\dummy\file00.txt
C:\Users\Mark\Desktop\dummy\folder01\file01_01.txt
C:\Users\Mark\Desktop\dummy\folder01\file01_02.txt
C:\Users\Mark\Desktop\dummy\folder01\file01_03.txt

C:\Users\Mark\Desktop\dummy\folder02\file02_01.txt
C:\Users\Mark\Desktop\dummy\folder02\file02_01.txt

C:\Users\Mark\Desktop\dummy\folder03\file03_01.txt
C:\Users\Mark\Desktop\dummy\folder03\file03_02.txt
C:\Users\Mark\Desktop\dummy\folder03\file03_03.txt
C:\Users\Mark\Desktop\dummy\folder03\file03_04.txt

Output with above code produces:

file00.txt 9
file01_01.txt 10
file01_02.txt 12
file01_03.txt 12
file02_01.txt 15
file02_01.txt 14
file03_01.txt 11
file03_02.txt 15
file03_03.txt 13
file03_04.txt 12

But what I want is:

file00.txt 9
\folder01\file01_01.txt 10
\folder01\file01_02.txt 12
\folder01\file01_03.txt 12
\folder02\file02_01.txt 15
\folder02\file02_01.txt 14
\folder03\file03_01.txt 11
\folder03\file03_02.txt 15
\folder03\file03_03.txt 13
\folder03\file03_04.txt 12

preceeding \, no slash, or .\ are fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别低头,皇冠会掉 2025-02-14 14:00:59

我建议您输出对象而不是像现在这样做的那样而不是字符串,无论如何,您可以使用 .substring(..)

foreach ($f in Get-ChildItem -Path $srcpth -File -Recurse) {
    [pscustomobject]@{
        FileName     = $f.Name
        FileSize     = $f.Length
        RelativePath = $f.FullName.Substring($srcpth.Length + 1)
    }
}

或者您使用 > PowerShell Core ,您可以访问.net api path.getRelativePath(String,string)

foreach ($f in Get-ChildItem -Path $srcpth -File -Recurse) {
    [pscustomobject]@{
        FileName     = $f.Name
        FileSize     = $f.Length
        RelativePath = [IO.Path]::GetRelativePath($srcpth, $f.FullName)
    }
}

还有< a href =“ https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.automation.automation.pathintrinsics.normalizarizerelative = wiew = powershellsdk-7.0.0.0.0.0 pathintrinsics.normalizerelative Path(String,String)方法 Windows PowerShell和PowerShell Core都可用

$ExecutionContext.SessionState.Path.NormalizeRelativePath($f.FullName, $srcpth)

I would recommend you to output objects instead of strings as you're doing right now, in any case, you can get the relative paths either using .SubString(..):

foreach ($f in Get-ChildItem -Path $srcpth -File -Recurse) {
    [pscustomobject]@{
        FileName     = $f.Name
        FileSize     = $f.Length
        RelativePath = $f.FullName.Substring($srcpth.Length + 1)
    }
}

Or if you're using PowerShell Core, you can access the .NET API Path.GetRelativePath(String, String):

foreach ($f in Get-ChildItem -Path $srcpth -File -Recurse) {
    [pscustomobject]@{
        FileName     = $f.Name
        FileSize     = $f.Length
        RelativePath = [IO.Path]::GetRelativePath($srcpth, $f.FullName)
    }
}

There is also PathIntrinsics.NormalizeRelativePath(String, String) Method available to both, Windows PowerShell and PowerShell Core, though this seems an overkill:

$ExecutionContext.SessionState.Path.NormalizeRelativePath($f.FullName, $srcpth)
仅此而已 2025-02-14 14:00:59

您可以在这里:

$srcpth = "C:\Users\Mark\Desktop\dummy\"
$files = Get-ChildItem -Path $srcpth -File -Recurse 

foreach ($f in $files) {
    $filen = $f.Name
    $filesize = $f.Length
    $relativePath = $f.fullname.remove(0,($srcpth.length))
    Write-Output "$filen $filesize $relativePath"
    }

没有任何您要寻找的值的对象属性。但是您可以像上面的那样计算它。当您试图弄清楚这样的东西时,查看对象的成员总是很有用的:

$files[0] | get-member

这将使您可以更好地了解可以使用什么,可以使用哪些属性以及可用的方法。

Here you go:

$srcpth = "C:\Users\Mark\Desktop\dummy\"
$files = Get-ChildItem -Path $srcpth -File -Recurse 

foreach ($f in $files) {
    $filen = $f.Name
    $filesize = $f.Length
    $relativePath = $f.fullname.remove(0,($srcpth.length))
    Write-Output "$filen $filesize $relativePath"
    }

There aren't any object properties with the value you're looking for. But you can calculate it like above. It's always useful to look at the members of an object when you're trying to figure something like this out:

$files[0] | get-member

This will give you a better idea of what you can work with, what properties you can use, and what methods are available.

荒路情人 2025-02-14 14:00:59

string.substring()/ .remove() [io.path] :: getRelativePath()解决方案在使用时就足够了仅绝对本地路径,当 -path get-childitem 的参数是 em avery 路径或a时,它们会失败。 powershell-folly-em>路径(请参阅本答案结束时的示例,以了解如何失败)。

对于另外支持PowerShell路径和相对路径的解决方案,我建议使用 resolve-path-relative

# For this demo, create a Powershell-only path.
$null = New-PSDrive -Name TempDrv -Root ([IO.Path]::GetTempPath()) -PSProvider FileSystem 
$srcpth = 'TempDrv:\RelativePathTest'
$null = New-Item "$srcpth\subdir\test.txt" -Force

# Set base path for Get-ChildItem and Resolve-Path. This is necessary because
# Resolve-Path -Relative resolves paths relative to the current directory.
Push-Location $srcpth

try {
    foreach ($f in Get-ChildItem -File -Recurse) {
        [pscustomobject]@{
            FileName     = $f.Name
            FileSize     = $f.Length
            RelativePath = Resolve-Path $f.FullName -Relative
            # Alternative to remove ".\" or "./" prefix from the path:
            # RelativePath = (Resolve-Path $f.FullName -Relative) -replace '^\.[\\/]'
        }
    }
}
finally {
    # Restore current directory even in case of script-terminating error
    Pop-Location
}

输出:

FileName FileSize RelativePath     
-------- -------- ------------     
test.txt        0 .\subdir\test.txt

模式的模式故障:

这是 string.substring()方法在我的系统上,在我系统上的powershell路径失败(您可能会看到不同的结果,取决于临时的位置目录):

FileName FileSize RelativePath  
-------- -------- ------------  
test.txt        0 ubdir\test.txt

这就是 [io.path] :: getRelativePath()失败:

FileName FileSize RelativePath  
-------- -------- ------------  
test.txt        0 ..\..\..\..\temp\RelativePathTest\subdir\test.txt

While the String.Substring() / .Remove() and [IO.Path]::GetRelativePath() solutions are sufficient when working with only absolute native paths, they fail when the -Path argument for Get-ChildItem is a relative path or a PowerShell-only path (see examples at the end of this answer for how they can fail).

For a solution that additionally supports PowerShell paths and relative paths, I recommend to use Resolve-Path -Relative:

# For this demo, create a Powershell-only path.
$null = New-PSDrive -Name TempDrv -Root ([IO.Path]::GetTempPath()) -PSProvider FileSystem 
$srcpth = 'TempDrv:\RelativePathTest'
$null = New-Item "$srcpth\subdir\test.txt" -Force

# Set base path for Get-ChildItem and Resolve-Path. This is necessary because
# Resolve-Path -Relative resolves paths relative to the current directory.
Push-Location $srcpth

try {
    foreach ($f in Get-ChildItem -File -Recurse) {
        [pscustomobject]@{
            FileName     = $f.Name
            FileSize     = $f.Length
            RelativePath = Resolve-Path $f.FullName -Relative
            # Alternative to remove ".\" or "./" prefix from the path:
            # RelativePath = (Resolve-Path $f.FullName -Relative) -replace '^\.[\\/]'
        }
    }
}
finally {
    # Restore current directory even in case of script-terminating error
    Pop-Location
}

Output:

FileName FileSize RelativePath     
-------- -------- ------------     
test.txt        0 .\subdir\test.txt

Modes of failure:

This is how the String.Substring() method fails for the PowerShell path of the sample above, on my system (you may see a different outcome depending on the location of your temp directory):

FileName FileSize RelativePath  
-------- -------- ------------  
test.txt        0 ubdir\test.txt

And this is how [IO.Path]::GetRelativePath() fails:

FileName FileSize RelativePath  
-------- -------- ------------  
test.txt        0 ..\..\..\..\temp\RelativePathTest\subdir\test.txt
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文