【发布时间】:2019-05-30 22:44:45
【问题描述】:
我基本上是在尝试构建一个读取命名文件夹目录的例程,构建一个 CSV 文件,然后读入该 CSV 文件,操作一些属性以将数据拆分为新列,然后将其导出到另一个 CSV。
这是我通过以下代码实现的:
$Folder = Read-Host 'Please enter a folder path'
$File = Read-Host 'Please enter a filename'
$OutputFile = $Folder + '\' + $File + '.csv'
$SplitFile = $Folder + '\' + $File + '_Split.csv'
$CopyDir = $Folder + '\WantedDocs\'
Get-ChildItem $Folder -Recurse -Include *.* |
select Directory, FullName, Name |
Export-Csv -Delimiter ',' -NoTypeInformation $OutputFile
$a = Import-Csv $OutputFile
$values = $a.Name.Split("_")
$a | Add-Member 'CliCode' -NotePropertyValue $values[3]
$a | Add-Member 'CopyDir' -NotePropertyValue $CopyDir
$a | Select Directory, FullName, Name, CliCode, CopyDir |
Export-Csv -Delimiter ',' -NoTypeInformation $SplitFile
如果我的术语不正确,请原谅,但我现在希望使用属性中的项目值构建一个包含 xcopy 命令的批处理文件。
xcopy 'C:\Test\OriginalDocs\A\file1_A_A_12345678.txt' 'C:\Test\WantedDocs\*' /Y
当您使用 Import-Csv 并将其分配给变量时,该变量包含各种属性,每个属性都包含从 CSV 文件中的每一行获取的值数组。
在我的示例中,变量 $a 具有名为“Directory”、“FullName”和“Name”的属性,它们是我的 CSV 文件中 3 列的标题。
如果我的 CSV 文件包含以下行:
"目录","全名","名称" "C:\Test\OriginalDocs\A","C:\Test\OriginalDocs\A\file1_A_A_12345678.txt","file1_A_A_12345678.txt" "C:\Test\OriginalDocs\B","C:\Test\OriginalDocs\B\file2_B_B_43534554.txt","file1_B_B_43534554.txt"Directory 属性将是一个包含 2 项的数组:“C:\Test\OriginalDocs\A”和“C:\Test\OriginalDocs\B\”
FullName 属性将是一个包含 2 项的数组:“C:\Test\OriginalDocs\A\file1_A_A_12345678.txt”和“C:\Test\OriginalDocs\B\file2_B_B_43534554.txt”
Name 属性将是一个包含 2 项的数组:“file1_A_A_12345678.txt”和“file2_B_B_43534554.txt”
我想知道的是如何为每个属性选择数组中的所有 [0] 项并构建 xcopy 命令
例如如果我这样做:
$xc1 = "xcopy '"
$xc2 = $a.FullName
$xc3 = "' '"
$xc4 = $a.CopyDir
$xc5 = $a.CliCode
$xc6 = "\*' /Y"
$xcopy = $xc1 + $xc2 + $xc3 + $xc4 + $xc5+ $xc6
生成的$xcopy 变量包含所有数组值
例如对于上面的示例,xcopy 变量以值结束:
xcopy 'C:\Test\OriginalDocs\A\file1_A_A_12345678.txt C:\Test\OriginalDocs\B\file2_B_B_43534554.txt' 'C:\Test\OriginalDocs\WantedDocs\ C:\Test\OriginalDocs\WantedDocs\12345678 43534554\*' /Y
我想要实现的是使用每个选定属性的 [0] 数组值有效地做到这一点:
$xc1 = "xcopy '"
$xc2 = $a.FullName[0]
$xc3 = "' '"
$xc4 = $a.CopyDir[0]
$xc5 = $a.CliCode[0]
$xc6 = "\*' /Y"
$xcopy = $xc1 + $xc2 + $xc3 + $xc4 + $xc5+ $xc6
将$xcopy 变量写入文本文件(我相信使用Add-Content)
然后对 [1] 数组值执行相同操作:
$xc1 = "xcopy '"
$xc2 = $a.FullName[1]
$xc3 = "' '"
$xc4 = $a.CopyDir[1]
$xc5 = $a.CliCode[1]
$xc6 = "\*' /Y"
$xcopy = $xc1 + $xc2 + $xc3 + $xc4 + $xc5+ $xc6
以此类推,直到处理完数组中的所有项目。
因此,为数组中的每个项目(即所有 [0]、所有 [1] 等)生成一个文本/批处理文件。
使用上面的示例,我会得到一个如下所示的文本文件。
xcopy 'C:\Test\OriginalDocs\A\file1_A_A_12345678.txt' 'C:\Test\OriginalDocs\WantedDocs\12345678\*' /Y
xcopy 'C:\Test\OriginalDocs\B\file2_B_B_43534554.txt' 'C:\Test\OriginalDocs\WantedDocs\43534554\*' /Y
我一直在查看foreach 和ForEach-Object,但到目前为止我还没有找到任何适合我需要的东西。可能做不到?
【问题讨论】:
-
读起来很长,但乍一看,您需要 1) 在
-NoteProperty和Value之间添加一个空格。 2)在使用之前检查,检查,双重检查任何用户输入。 3) 在组合文件夹和文件名时使用Join-Pathcmdlet,而不是硬编码反斜杠。那么.. 为什么要使用XCOPY而不是简单地遍历 CSV 中的所有行,为该特定文件创建路径并在其上执行Copy-Item? -
你真的应该阅读minimal reproducible example 是什么,否则你会很快失去你的观众。 How-to ask
-
嗨@Theo 感谢您的回复。我需要在将文件复制到的目标目录中创建新目录。据我了解,如果源项目是文件,则 Copy-Item 不会创建新文件夹。尝试此操作时出现错误: $b = Import-Csv $SplitFile Foreach ($Row in $b) { $OriginalFile = $($Row.FullName) $CopyFile = $CopyDir + $($Row.CliCode) Copy -Item $OriginalFile -Destination $CopyFile -Force -Recurse }
-
执行“文本”使用
Invoke-Expression。但我宁愿使用没有xcopy的纯powershell 解决方案。 -
是的,您需要确保文件的路径存在。您可以使用
Test-Path和New-Itemcmdlet 来做到这一点。
标签: arrays powershell csv import-csv export-csv