我发现这可以获取 CSV 文件中文件夹及其子文件夹(仅文件)的内容:
dir -recurse | Where-Object { !$_.PSIsContainer } | Select FullName |
convertto-csv | out-file "test.csv"
但是,我想要获取相对路径(相对于我运行命令的根目录),而不是完整路径。
有人可以帮忙吗?
谢谢!
答案1
获取正确的 Csv 文件的一种方法是包装我的评论的输出:
Get-ChildItem -Recurse -Name -File |
ForEach-Object -begin {'"RelativePath"'}{'"{0}"' -f $_}|
Out-File "test.csv"
或者使用计算属性从属性中去除起始目录FullName
。
$StartDir = "$ENV:USERPROFILE\Documents\"
Get-ChildItem -Path $StartDir -File -Recurse |
Select-Object @{n='RelativePath';e={$_.FullName -replace [regex]::escape($StartDir)}}|
Export-Csv 'test.csv' -NoTypeInformation
答案2
这个问题给人的印象是您对 PowerShell 非常陌生。因此,您必须加强对它的了解,以限制/避免您肯定会遇到的误解、坏习惯、错误和严重的挫折。访问 YouTube/MSDN Channel9 并搜索初级、中级、高级 PowerShell,以及 PowerShell 文件系统管理和 PowerShell 文件和文件夹管理。
在很多情况下,PowerShell 会尝试强制执行某些操作,但它不会尝试弄清楚您想要做什么。您必须告诉它要做什么。嗯,对于任何计算机语言来说都是如此。
你这里的问题就是你所说的......
(相对于我运行命令的根目录)
... 好吧,你可能处于距离根驱动器 X 级深度的路径中,所以,现在你处于子驱动器中,并且推断你只想从子驱动器中获取此信息。这就是这种思维过程的难点所在。
将其保存到文本文件中,那么就永远不会有驱动器路径,因此当您返回使用它时,您必须知道这一点并将其手动放回去才能再次使用这些文件。
因此,我不确定您的用例是什么,但从逻辑上讲,它会给您带来麻烦。
假设我在这里:
Push-Location -Path 'E:\Temp'
然后我们运行这个
Get-ChildItem -recurse |
Where-Object { !$_.PSIsContainer } | Select-Object -Property FullName
# Results
FullName
--------
E:\Temp\about_ReGet-ChildItemection Microsoft Docs.url
...
E:\Temp\ZipMultiFolder.zip
E:\Temp\Folder\Log_20190419.txt
...
E:\Temp\Reports\NewFiles.zip
...
所以,这里我们只获取当前位置...
Get-ChildItem -recurse |
Where-Object { !$_.PSIsContainer } |
Select-Object -Property @{Name = 'RelativePath';Expression = {"\$($pwd.Drive.CurrentLocation)\$($PSItem.Name)"}}
因此,这里我们只获取当前所在的路径,并且只询问文件名,而不是全名
# Results
RelativePath
------------
\Temp\about_ReGet-ChildItemection Microsoft Docs.url
...
\Temp\ZipMultiFolder.zip
\Temp\Folder\Log_20190419.txt
...
\Temp\Reports\NewFiles.zip
...
如果我们将其输出到 CSV,您就不知道它来自哪个驱动器。因此,现在您必须搜索机器上的每个驱动器才能找到它们,或者记住执行此操作时的位置。
再往下看一个孩子,也是一样。当然,你明白了,但它到底在哪里?在你的系统上,或者在你映射到的某个网络驱动器上。
Push-Location -Path 'E:\Temp\Folder'
然后我们运行这个
Get-ChildItem -recurse |
Where-Object { !$_.PSIsContainer } | Select-Object -Property FullName
# Results
FullName
--------
E:\Temp\Folder\Log_20190419.txt
E:\Temp\Folder\New Bitmap Image.bmp
E:\Temp\Folder\New Text Document - Copy.txt
E:\Temp\Folder\New Text Document.txt
Get-ChildItem -recurse |
Where-Object { !$_.PSIsContainer } |
Select-Object -Property @{Name = 'RelativePath';Expression = {"\$($pwd.Drive.CurrentLocation)\$($PSItem.Name)"}}
RelativePath
------------
\Temp\Folder\Log_20190419.txt
\Temp\Folder\New Bitmap Image.bmp
\Temp\Folder\New Text Document - Copy.txt
\Temp\Folder\New Text Document.txt
如果你在这里说,你不想要父根,那么你就把它关闭。
然而,这意味着,您不仅不知道它来自哪个驱动器,而且也不知道它的根父级来自哪个。
所以,只是说说而已。
顺便说一句,在脚本中使用完整的 cmdlet 名称是一种最佳实践。简写/别名对于交互式内容来说很好。当然,我们都习惯使用“dir”,但 Get-ChildItem 的简写是“gci”,它和 did 一样短,但是,你知道的。
Get-Alias -Definition Get-ChildItem |
Format-Table -AutoSize
CommandType Name Version Source
----------- ---- ------- ------
Alias dir -> Get-ChildItem
Alias gci -> Get-ChildItem
Alias ls -> Get-ChildItem
但是,习惯真的很难改变。;-} --- --- 而明智的决定是那些对我们有用的决定,不管别人怎么想。;-}
好吧,那些跟随你的人会采取立场。所以成为一名优秀的 PowerShell 公民确实是一件好事。
顺便说一句,如果您要在脚本中执行此操作,也有用于此类操作的自动变量。好吧,获取脚本运行的位置以及与该位置相关的任何内容。
请参阅此文章。