【问题标题】:Converting CSV from Data Table to Key Value Pairs in Powershell在 Powershell 中将 CSV 从数据表转换为键值对
【发布时间】:2018-08-18 10:45:05
【问题描述】:

我正在编写一个脚本,该脚本需要处理相同类型的文件,但在不同时间具有不同的内容。我有一个类似于以下示例的 CSV 文件。并非每个字段都可能包含值。

record,title,creator,date,subject,location 0,Title1,Creator1,2018-08-17,Subject1,Location1 1,Title2,Creator2,2018-08-17,,Location1 2,Title3,Creator3,,Subject2,Location2

我需要将此 CSV 从数据表转换为键值对列表,每条记录,仅当存在值时。标题将是通用的,field,value 为行中的每个键值对重复。例如:

record,field,value,field,value,field,value,field,value,field,value 0,title,Title1,creator,Creator1,date,2018-08-17,subject,Subject1,location,Location1 1,title,Title2,creator,Creator2,date,2018-08-17,location,Location1,,, 2,title,Title3,creator,Creator3,subject,Subject2,location,Location2,,,

我可以使用Import-CSV 读取 CSV,但我很难更改结构。我尝试过的每条路径都没有结果,与寻找解决方案一样。在这一点上,手动构建新的 CSV 似乎是最简单的,但这似乎不对,所以我想我会在这里问。谁能指出我正确的方向?

我可以在 StackOverflow 上找到很多 CSV、哈希表和键值对问题,但没有像这样的问题。

【问题讨论】:

  • 您在第二个 CSV 示例中存在不一致。您显示除“记录”之外的所有内容的键/值。这是故意的吗?
  • 是的,这是故意的。记录列是数字对象的标识符,键/值是元数据属性。我必须将从一个系统导出的数据表转换为一组键/值对,但仍与一条记录相关联。 (在 CSV 中。)

标签: powershell csv


【解决方案1】:

我认为您误解了Import-Csv 的工作原理。它不创建哈希表,而是创建对象数组。每个对象都有一组属性,由标题定义。由于数据是从 CSV 导入的,因此它通过保证每个对象具有相同的属性(它们可能没有值,但属性存在并且相同)来简化事情。因此,我们可以将第一个对象的属性列表作为基线集,然后遍历每条记录并根据该基线为每条记录构建一个字符串。正如您所建议的,我们将手动构建 CSV。

$DataIn = Import-Csv C:\Path\To\File.csv
$Props = $DataIn[0].psobject.properties.name
$DataOut = ('record,'+$((2..$Props.Count|%{'field,value'}) -join ',')),$(For($i=0;$i -lt $DataIn.count;$i++){
    [array]$tmpRecord = Switch($Props){
        'Record' {$DataIn[$i].record;continue}
        {[string]::IsNullOrEmpty($DataIn[$i].$_)} {continue}
        default {'{0},{1}' -f $_, $DataIn[$i].$_}
    }
    If(($tmpDiff = $Props.count - $tmpRecord.count) -gt 0){$tmpRecord += ','*($tmpDiff*2-1)}
    $tmpRecord -join ','
})
$DataOut | Set-Content C:\Path\To\Output.csv

所以这完全符合我的建议,同时保留了不为 record 列执行键/值的示例输出。 switch 检查每个潜在属性,如果它是“记录”属性,它只输出记录值并继续到下一个属性。如果它是其他任何东西,它会检查该属性是否为空白,如果是,则移动到下一个属性。如果它不是空白,则输出field,value,然后所有这些输出(记录和任何字段/值组合)通过逗号连接到每条记录的一行中。它还为空字段添加了额外的逗号。每条记录的行与计算的标题行一起收集在$DataOut 中。

请注意,PowerShell 不希望使用 Import-Csv 读取该文件,因为重复的列是因为标题行主要是“字段,值”一遍又一遍地重复。我假设您正在以这种格式保存一些需要该格式进行输入的外部程序。

【讨论】:

  • 谢谢。我之前使用哈希表时说错了,应该说数据表。我不是指import-csv 如何解析数据,而是指数据如何在原始 CSV 本身中建模。这个解决方案听起来会起作用,谢谢。我期待着对其进行测试。 CSV 将用于另一个程序,重复的标题可能有问题,但我希望它会被跳过。我会回来报告的。
  • Huzzah,它按描述工作!我不需要将'record,+ 添加到 $DataOut 中,因为该列与 $Props 一起出现。
  • 我确实有一个次要问题。一些值是双引号并包含空格和逗号,因此拆分为键/值对是不正确的。例如,“ Title/“Chapter 4, Page 1”的 key/value 出来了 Title/Chapter 4 和 Page 1/Format。(Format/book 是下一个 key/value。)
  • 知道了,[char]34 +
猜你喜欢
  • 1970-01-01
  • 2013-12-02
  • 2016-07-02
  • 2021-05-16
  • 2021-10-10
  • 2021-01-08
  • 2016-09-19
  • 2020-06-10
  • 1970-01-01
相关资源
最近更新 更多