【问题标题】:Ignore newlines in CSV value忽略 CSV 值中的换行符
【发布时间】:2010-03-05 21:18:56
【问题描述】:

所以我有一个包含文件名和文件内容的 CSV。该文件充满了换行符和各种其他字符。我需要让每一行在一个列中包含文件名,在下一列中包含文件内容,然后我需要一个新行,直到文件末尾。

数据如下:

"filename.txt","hey there
buddy
how are you
doing"
"filename2.txt","and so on..."

根据http://creativyst.com/Doc/Articles/CSV/CSV01.htm#EmbedBRs,我的 CSV 导入器应该将这些换行值读取为单个值,而不是新行。但是,我尝试过 OO Calc、KSpread、Gnumeric,甚至 Microsoft Excel 2007,但没有一个是这样读的;他们都认为每个换行符都是一个新行。

有人知道如何解决这个问题吗?我查看了其他相关问题,但似乎都没有说。

如果这不起作用,我将不得不直接使用 Python Excel 编写模块或其他东西编写文件。有人知道在这里做什么吗?

【问题讨论】:

  • 没有 CSV 标准......只是一个预期的标准,这正是 CSV 糟糕的原因。
  • CSV standard,但大多数实现不遵守它。

标签: csv newline


【解决方案1】:

文件必须具有 .csv 扩展名。否则似乎不起作用。就我而言,Excel 中的错误。

【讨论】:

    【解决方案2】:

    如果您设置了适当的标志,免费的LumenWorks CSV reader 会处理数据中的换行符。

    【讨论】:

      【解决方案3】:

      Excel 2007 可以很好地读取它们,但您仍然会在列中看到回车符。

      您需要在导入文件之前删除它们。

      如果您自己从 SQL Server 创建文件,则可以轻松删除它们。

      REPLACE(REPLACE(Field, CHAR(13),' '), CHAR(10), ' ') AS FixedField
      

      【讨论】:

        【解决方案4】:

        我不得不切换到直接执行 Excel 格式 I/O 的东西,我没有让 Excel 按预期从 CSV 解析换行符。

        即便如此,它也没有成功,因为 Excel 对每个单元格的字符数有严格的限制。客户决定不再继续这样做,并与他们需要 Excel 文件的软件的开发人员一起制定了替代提交流程。

        【讨论】:

          【解决方案5】:

          好吧,如果输入文件可能包含任何内容,那么它也可能包含引号、逗号等任何会破坏整个表格的内容。

          我建议其中之一:

          • 使用不同的格式:如XML或HTML表格,可直接导入Excel

          • 使用 Excel 函数(或 VBasic)转义文件中的换行符并在 Excel 中拆分它们

          我认为,只有当您以简单的形式拥有可预测且简单的数据时,使用 CSV 才是一个合理的选择,这样您就可以保持“一行 = 一行”的规则。 (然后您可以使用 printf 完成所有工作,这很酷。:D)

          【讨论】:

            【解决方案6】:

            导入时指定引号 (") 作为文本限定符。然后将忽略换行符。

            【讨论】:

            • 我这样做了,但似乎没有什么不同。我使用 """" 作为引号字符有一段时间了,因为我的文件的内容可能包含 "。尝试了所有这些都没有区别。现在使用 " 作为引号和 , 作为分隔符,因为链接的站点说 Excel 会读取那是正确的。它没有。
            • 从您尝试解析 csv 的工具集来看,我还冒昧地猜测可能会与 *nix 换行符和 Windows 的回车 + 换行符混淆。 IE。 Excel 不会将换行识别为正确的换行符。
            【解决方案7】:

            如果您的 .csv 文件包含引用的多行字段,只需 chr(10) (0x0A) 进行中断(这似乎是 Excel 2007 导出的 .csv 文件的默认设置),而不是 chr(13)+chr(10),然后是标准 VBA 文件处理使用line input #1split 可以正常工作。结果是您获得了该字段的单个动态数组元素,其中包含换行符。

            可能在字段 3 (4) 中有换行符的 csv 文件示例:

            dim recFields as variant
            dim rec as string
            open "testfile.csv" for input as #1
            line input #1, rec
            while not eof(1)
                recFields = split(rec,vbTab)
                recFields(3) = replace(recFields(3),chr(10),"|")
                ' May want to remove quotes as well
                recFields(3) = replace(recFields(3),chr(34),"")
                ' Do some stuff here.
                ' Then read next record
                line input #1,rec
            wend
            close #1
            

            关键是在字段中只用0x0A 表示换行符,而不是0x0C+0x0A,并使用动态(变体)数组来拆分记录。我害怕不得不处理这种情况,直到我意识到在良好的旧 VBA 下,它才有效。避免了先读后退(例如使用 PHP 的ftellfseek)的可怕替代方案!

            【讨论】:

              【解决方案8】:

              谢谢亚历克斯 P!这为我将文本从 Scrivener 导出到 Excel 提供了一种更好的方法。这是我对 VBA 脚本的变体:

                  Sub importScriv()
              
              Dim recFields As Variant
              Dim rec, rec2 As String
              Dim index, row, col, numcols
              Dim FileName
              
              FileName = ThisWorkbook.Path & "/scriv.txt"
              
              Open FileName For Input As #1
              Line Input #1, rec
              ' Get next line
              Line Input #1, rec2
              row = 1
              
              While Not EOF(1)
                  ' The Scrivner compile needs to put a % + Tab character as the first thing in the Section Layout Prefix
                  ' The % is used to demark Scrivener documents
                  Do While Left(rec2, 1) <> "%"
                      rec = rec & rec2 & Chr(13)
                      ' Get next line
                      Line Input #1, rec2
                      If EOF(1) Then GoTo Finish
                  Loop
              
                  ' Split the lines at the tab seprators
                  recFields = Split(rec, vbTab)
                  numcols = UBound(recFields) - LBound(recFields) + 1
              
                  ' put the data in the row
                  For col = 1 To numcols
                      ' Remove any leading carriage returns
                      If Left(recFields(col - 1), 1) = CHR(13) Then
                        recFields(col - 1) = Right(recFields(col - 1), Len(recFields(col - 1)) - 1)
                      End If
                      Cells(row, col) = recFields(col - 1)
                  Next col
              
                  ' We got a % in rec2 so set rec to rec2
                  rec = rec2
              
                  ' increment the row
                  row = row + 1
                  ' Get next line
                  Line Input #1, rec2
              Wend
              
              Finish: Close #1
              
              ' Finally, delete the first column that contains the % document separator characters
              Columns(1).EntireColumn.Delete
              
              End Sub
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2021-06-17
                • 2017-03-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多