使用Powershell的Get-ChildItem命令将详细信息导出为CSV文件

3

我正在尝试为具有深层文件夹结构的文件共享创建CSV文件。

我希望CSV文件如下所示:

filename, filepath, file type, folderStructure

目前我有以下内容:

#Get-ChildItem -Path D:\ -Recurse
$directory="d:\"
gci $directory -recurse |
where {$_.psiscontainer} |
foreach {
    get-childitem $_.fullname |
    sort creationtime |
    select -expand fullname -last 1
}

你能够伪造输出的样式吗? 比如: image.png, D:\images, .png, D:\images lister.csv, D:\images\Lists, .csv, D:\images\Lists - Austin T French
我明白了,但您能否提供一些数据(格式可以用虚假的)以便我确认您的需求?特别是文件夹结构。您想要类似于以下这样的东西吗? D:
+图像 ++ image1.jpg +列表 ++导出 +++ export1.xlsx +++ Export4.csv
- Austin T French
3个回答

9

在PowerShell中,您不需要递归递归。它将自动遍历所有子目录的子目录。

我对您想要的一些信息也有点不确定,但是这里有一个脚本,我相信它可以实现您想要的大部分功能,并且在我看来更易读。

Get-ChildItem -Path X:\Test -Recurse |`
foreach{
$Item = $_
$Type = $_.Extension
$Path = $_.FullName
$Folder = $_.PSIsContainer
$Age = $_.CreationTime

$Path | Select-Object `
    @{n="Name";e={$Item}},`
    @{n="Created";e={$Age}},`
    @{n="filePath";e={$Path}},`
    @{n="Extension";e={if($Folder){"Folder"}else{$Type}}}`
}| Export-Csv X:\Test\Results.csv -NoTypeInformation 

由于我创建了这个测试,您需要更改路径。 我在Excel中的结果如下:

+-------------------------------+----------------+-------------------------------------+-----------+
|             Name              |    Created     |              filePath               | Extension |
+-------------------------------+----------------+-------------------------------------+-----------+
|         test2                 | 3/6/2013 19:21 | X:\Test\test2                       | Folder    |
|         Results.csv           | 3/6/2013 19:51 | X:\Test\Results.csv                 | .csv      |
|         test3                 | 3/6/2013 19:21 | X:\Test\test2\test3                 | Folder    |
|         New Text Document.txt | 3/6/2013 19:21 | X:\Test\test2\New Text Document.txt | .txt      |
+-------------------------------+----------------+-------------------------------------+-----------+

在扩展名处,如果显示的是"文件夹",则应该返回它是一个目录而不是空白(没有扩展名)。


那个属性是Parent,所以如果你把$.Fullname改成$.Parent,它就可以工作了,但为了可读性,你也可以将变量名更改为$Parent,然后更新行@{n="filePath";e={$Path}},为@{n="Folder Name";e={$Parent}}, - Austin T French
糟糕,这个问题有点短视。因为你将在根目录 "D:" 下,所以你也需要填充它。否则,你最终会在 D:\ 上没有任何导出。 所以,请将你的选择对象更改为 @{n="文件夹名称";e={if($Parent){$Parent}else{"根目录"}}},` - Austin T French
Get-ChildItem -Path d:\ -Recurse |` foreach{ $Item = $_ $Type = $.Extension $Path = $.FullName $FolderPath = $.Parent $Folder = $.PSIsContainer $Age = $_.CreationTime$Path | Select-Object @{n="名称";e={$Item}}, @{n="创建时间";e={$Age}}, @{n="文件路径";e={$Path}}, @{n="文件夹目录";e={$FolderPath}}, @{n="扩展名";e={if($Folder){"文件夹"}else{$Type}}} }| Export-Csv d:\结果.csv -NoTypeInformation - torres
你正在解析什么?缺少多少个文件?还是整个目录都没有了?在 PS 窗口中有任何错误吗?从 PowerGUI 运行它或从打开的 PS shell 中调用它,这样它就不会自动关闭。 - Austin T French
我认为它没有报告根容器,请添加并再次发布结果。现在也很晚了,所以今晚就这样吧。谁知道,也许我的大脑一开始就不正常...@ {n="Container";e={$Folder}},` - Austin T French

1

好的,我更改了检查父级的方式。它不再直接查看Parent属性,现在应该已经修正了。

    Get-ChildItem -Path D:\ -Recurse |`
foreach{
$Item = $_
$Type = $_.Extension
$Path = $_.FullName

$ParentS = ($_.Fullname).split("\")
$Parent = $ParentS[@($ParentS.Length - 2)]

$Folder = $_.PSIsContainer
$Age = $_.CreationTime

$Path | Select-Object `
    @{n="Name";e={$Item}},`
    @{n="Created";e={$Age}},`
    @{n="Folder Name";e={if($Parent){$Parent}else{$Parent}}},`
    @{n="filePath";e={$Path}},`
    @{n="Extension";e={if($Folder){"Folder"}else{$Type}}}`
}| Export-Csv X:\Test\ResultsC.csv -NoTypeInformation 

现在它正在获取当前项的路径,通过在\上拆分将其转换为数组,然后给出ArryLength - 2处的值。

在这里我该怎么做才能获取完整路径(不包括文件名)?$ParentS[@($ParentS.Length - 2)] - torres
我添加了一个新变量 $ParentPath = $_.PSParentPath,它基本上可以工作,但是会返回这个结果 "Microsoft.PowerShell.Core\FileSystem::D:\Install Files\AutoSPInstaller\SP2010\AutoSPInstaller"。其中的 "Microsoft.PowerShell.Core\FileSystem::" 是多余的,我不需要它。 - torres
Fullname是返回完整路径的属性,例如D:\Folder1\Images\Image1.jpg。 $ParentS = ($_.Fullname).split("") $Parent = $ParentS[@($ParentS.Length - 2)] 这将给您文件夹路径 - 实际的文件名。 - Austin T French

1

我不确定这是否是最佳方法,但它有效。我有一种感觉可以缩短代码以获取文件的完整路径。

$myDirectory = "D:\"
Get-ChildItem -Path $myDirectory -Recurse |`
foreach{
$Item = $_
$Type = $_.Extension
$Path = $_.FullName

$ParentS = ($_.Fullname).split("\")
$Parent = $ParentS[@($ParentS.Length - 2)]
$ParentPath = $_.PSParentPath
$ParentPathSplit = ($_.PSParentPath).split("::")
$ParentPathFinal = $ParentPathSplit[@($ParentPathSplit.Length -1)]
#$ParentPath = [io.path]::GetDirectoryName($myDirectory)

$Folder = $_.PSIsContainer
$Age = $_.CreationTime

$Path | Select-Object `
    @{n="Name";e={$Item}},`
    @{n="Created";e={$Age}},`
    @{n="Folder Name";e={if($Parent){$Parent}else{$Parent}}},`
    @{n="filePath";e={$Path}},`
    @{n="Extension";e={if($Folder){"Folder"}else{$Type}}},`
    @{n="Folder Name 2";e={if($Parent){$Parent}else{$Parent}}},`
    #@{n="Folder Path";e={$ParentPath}},`
    @{n="Folder Path 2";e={$ParentPathFinal}}`

}| Export-Csv d:\ResultsC_2_F.csv -NoTypeInformation 

1
是的,FullName是全名属性。 使用PS,您还可以执行 DIR | FL * 这将提供所有可用属性(某些属性不会在get-childitems中返回值),然后您可以使用$_.AttributeName获取该值。一旦您知道哪些属性有效,就可以进行字符串操作。代码可能会更短,但为什么呢?可读性比节省几行代码更重要,执行时间和文件大小差异非常小。 - Austin T French

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接