【问题标题】:Handle a CSV file with single quoted string and occasional comma or single quote within the single quoted string处理带有单引号字符串和单引号字符串中的偶尔逗号或单引号的 CSV 文件
【发布时间】:2015-09-16 14:48:18
【问题描述】:

我有一个 CSV 文件,其中的文本列用单引号括起来,而其他非文本列周围没有引号。文本列在这些单引号文本列中可能有逗号或单引号。我在网上找到了一个脚本,但它不能处理这种情况。

有没有办法在 PowerShell 中处理这个问题?

例子:

123,678.89,'hello there1', 'xyz1@gmail.com', 'abc,nds'\n 
123,678.89,'hello 'there2', 'xyz2@gmail.com', 'akiu-'nds'\n

输出:

123,678.89|hello there1|xyz1@gmail.com|abc,nds \n 
123,678.89|hello 'there2|xyz2@gmail.com|akiu-'nds \n

示例 2:
123,6272,678.89,,,'hello ,there1',,,,'abc1','tw,es',,'xyz1@gmail.com',,,,,,'abc,nds1'\n 124,8272,928.89,,,,'hello 'there2',,,'abc2','twes',,,'xyz2@gmail.com',,'biej',,,'abc'nds2'\n 125,9272,328.89,,'你好'there3',,'abc3',',outyi',,,,'xyz3@gmail.com',,,,,,'ahct','abc'nds3'\n

输出:

123|6272|678.89|||你好,there1||||abc1|tw,es||xyz1@gmail.com||||||abc,nds1\n 124|8272|928.89||||你好'there2|||abc2|twes|||xyz2@gmail.com||biej|||abc'nds2\n 125|9272|328.89||你好'there3||abc3|, outyi||||xyz3@gmail.com||||||ahct|abc'nds3\n

【问题讨论】:

    标签: string powershell csv


    【解决方案1】:

    类似于Kiran's answer。有几件事需要改变,所以我不认为有一个万能的解决方案。我们需要链接这两个更改。首先是实际分隔符的逗号,其次是特殊的行尾字符序列。

    $path = "c:\temp\file.csv"
    $newDelimiter = "|"
    (Get-Content $path) -replace "'\s*?,\s?'|,\s?'|'\s?,",$newDelimiter -replace "'\s*?\\n$","\n" | Set-Content $path
    

    我有一个regex101 link 可以更详细地解释。做更多工作的正则表达式是第一个具有三个潜在替代匹配的正则表达式。这有效地忽略了自己关闭的引号。如果有数据包含引号和逗号组合,那么我认为在没有更多信息的情况下对其进行编程。

    • '\s*?,\s?':逗号括在引号中,可选地被变体空格包围。
    • ,\s?':逗号加上可选空格,后跟引号
    • '\s?,: 引用可选空格,后跟逗号

    因此,上述任何组的匹配项都将替换为$newDelimiter。第二个正则表达式只是在寻找'\n$,同时考虑到引号和\n之间的潜在可选空格,这些空格发生在行尾。这就是删除最后一个单引号的方式。

    【讨论】:

    • 我以为我得到了完整的数据,但在我的初始示例中我没有,但我添加了示例 2,它可以更清晰地了解数据格式。我尝试使用您的代码,但无法将数据转换为所需的格式。
    • 我只想将逗号替换为新的分隔符,并在单引号包裹的文本值中保留现有的逗号或引号。如果可能的话,还要尝试去掉字符串周围的引号。
    【解决方案2】:

    这样的?

    Get-Content C:\temp\file.txt | 
       ForEach-Object {$_ -replace ",'|',\s+'",'|' -replace "'\\n",' \n'} | 
           Set-Content C:\temp\newfile.txt 
    

    注意:代码只有一行,为了便于阅读,分成了 3 行。

    【讨论】:

    • 仅对以单引号开头的列更改分隔符,而我无法将其用于其余数据。
    猜你喜欢
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多