【问题标题】:PowerShell Import-CSV to Export-CSV with type conversionPowerShell Import-CSV 到 Export-CSV 的类型转换
【发布时间】:2017-10-19 23:29:21
【问题描述】:

我得到一堆制表符分隔的文件,我想将它们转换为逗号分隔的文件。我也只需要文件“Date”和“Value1”中的两列,所以我删除了其余的列。

Date    Value1  Value2  Value3  Value4  Sensor
08.07.2010  115,28  115,45  115,45  115,28  100
07.07.2010  115,34  115,32  115,34  115,25  85
06.07.2010  115,23  115,74  115,74  115,20  203

它的工作原理如下:

(get-ChildItem -Path '*.txt').name | ForEach-Object { 
    Import-Csv -Path $_ -Delimiter "`t" | 
    Select-Object -Property Date,Value1 | 
    Export-Csv "out\$_" 
}

不幸的是,在源文件中逗号用作小数分隔符。所以我得到这些文件,其中 Value1 被解释为字符串:

"Date","Value1"
"24.02.2017","30,18"
"23.02.2017","30,20"
"22.02.2017","30,18"
"21.02.2017","30,18"
"20.02.2017","30,17"

如何将列的数据类型设置为数字? Import-CSV期间?

【问题讨论】:

  • 你能分享一下初始的 CSV 吗?
  • 已添加。我在插入标签时遇到了一些问题......但现在它似乎正确显示了。

标签: powershell csv import-csv


【解决方案1】:

Export-CSV总是在输出字段值周围添加"..."(本身)不是问题:

  • CSV 数据格式没有数据类型的内在概念,并且双引号被单独使用将字段值括起来(例如,这是嵌入, 字符的字段值的语法要求)。

  • 例如,Excel 推断一列的数据类型仅根据其内容,无论该内容是否用双引号括起来。

    • 但是,内容解释是文化感知(locale-aware)
  • 相比之下,PowerShell 的Import-Csv 从不 解释数据并将所有字段值返回为字符串强>.

根据将在其中处理 CSV 的环境中的活动区域性,您有两种选择:

  • 对于诸如de-DE(德国)之类的文化,其中,(逗号)而不是.(点、句点)用作小数点,并且使用;而不是,作为列表分隔符:

    • 在目标区域性生效的情况下(使用Get-Culture 验证)使用Export-Csv -UseCulture
      -UseCulture 从(至少)v2[1] 起可用 ).谢谢,LotPings
    • 或者,使用类似Export-Csv -Delimiter ([cultureinfo]::GetCultureInfo('de-DE').TextInfo.ListSeparator)
  • 对于英语文化(或使用. 作为小数点的任何其他文化):

    • 自定义处理文件将数字字段中的 , 实例替换为 . - 见下文。

要将, 实例替换为.,以下仅使用字符串操作的命令可以:

Get-ChildItem -Path *.txt | ForEach-Object {
  Get-Content -LiteralPath $_.FullName | ForEach-Object {
    ($_ -split '\t')[0,1] -replace ',', '.' -join ','
  } |
    Set-Content -Encoding utf8 "out/$($_.Name)"
}

注意:为简单起见,该命令假定 Date 列值不包含 , 的实例,并且所有值都不需要 "..."-enclosure - 这在这种特定情况下是合理的。

  • 我已选择 UTF-8 作为上面的输出编码,因为 Set-Content 默认为旧的、特定于文化的“ANSI”代码页 - 根据需要进行调整。

[1] 通常,如果 cmdlet 帮助主题中的参数描述未提及引入它的特定版本,则暗示它自 v2.0 起就已存在。您现在可以GitHub浏览文档的旧版本 - 低至 v3 - 只需输入 T 或单击 Find file 并开始输入 cmdlet / 概念性帮助主题名称。支持>

【讨论】:

    【解决方案2】:

    Export-CSV 添加引号,无论类型如何。您可能唯一能做的就是再次加载文件并使用 regex 删除这些引号:

    (get-ChildItem -Path '*.txt').name | ForEach-Object { 
        Import-Csv -Path $_ -Delimiter "`t" | 
        Select-Object -Property Date,Value1 | 
        Export-Csv "out\$_" 
        (Get-Content $_) -replace ',"(\d+),(\d+)"$', ',$1.$2'  | Set-Content "out\$_"
    }
    

    注意:您可能需要为Set-Content cmdlet 设置-Encoding

    【讨论】:

    • 这给了我链接这个 "22.07.2016",8,47 的行...不是我所期望的,因为 8,47 将被解释为两列
    • 您还应该将 Get-Content/Set-Content $_ 更改为 out\$_ ... 因为我刚刚擦除了 PC 上的输入文件 :) ... 现在我将必须等到星期一才能在办公室拿到新副本。
    • uppps,很抱歉:p
    • 顺便说一句,如果该文件夹已编入索引,只需右键单击它并选择恢复以前的版本。
    猜你喜欢
    • 2018-06-03
    • 2016-01-07
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2018-02-08
    • 1970-01-01
    • 2014-12-24
    相关资源
    最近更新 更多