【问题标题】:Python issue outputting multiline string into single csv.writer rowPython问题将多行字符串输出到单个csv.writer行
【发布时间】:2016-06-01 11:28:54
【问题描述】:

以下代码有效,但将多行字符串的每个换行符分配给新行,而不是一个单元格的所需状态。

在研究可能的解决方案时,我读到:

  • 我应该尝试用双引号将字符串括起来
  • newline 替换为carriage return 会有所帮助
  • 通过[]声明解析为列表/元组

在尝试了上述所有方法后,我对为什么这不起作用感到非常困惑。如果我删除newline,它会将所有内容分配给行中的单个单元格,但很难阅读。

输出带有csv.writer的字符串时有没有办法保留格式?

def run_rip():
os.chdir('/REGRIPPERDIR/RegRipper2.8')
for k in ntDict:
    run_command = "".join(["./rip.pl", " -r /APATH/NTUSER.DAT -p ", str(k)])
    process = subprocess.Popen(run_command,
                               shell=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    out, err = process.communicate()
    pattern = re.compile('lastwrite|(\d{2}:\d{2}:\d{2})|alert|trust|Value')
    grouping = re.compile('(?P<first>.+?)(\n)(?P<second>.+?)([\n]{2})(?P<rest>.+[\n])', re.MULTILINE | re.DOTALL)
    if pattern.findall(out):
        match = re.search(grouping, out)
        first = match.group('first')
        second =match.group('second')
        rest = ('"%s' % os.linesep.join([s for s in match.group('rest').splitlines() if s]))
        rest = rest.replace('\n','\r\n')
        headers = ['Name', 'Description', 'Found']
        f = csv.writer(open('/APATH/ntuser.csv', 'ab'),
                       dialect=csv.excel,
                       delimiter='\t')
        f.writerow(headers)
        f.writerow((first, second, rest))
        print(out)
    ntDict.popitem(last=False)

run_rip()

样本输出:

/edit:我被要求在下面的 cmets 中发布第三个字符串 rest 的样本,因为它已被收集。以下文本将传递给csv.writer

Baseline\n #First string as defined by the regex
(All) scans a hive\n #Second String as defined by the regex

Total values checked    : 64\n   #This and below is the rest string
Number of binary value lengths : 11\n
...\n
Value -5: 176 bytes [# times: 1]\n
Value -4: 712 bytes [# times: 5]\n

期望状态:

【问题讨论】:

  • 我可以建议您发布一些 csv 文本(即字符串),以提供所需的布局吗?根本问题是 csv 并不是真正的标准。您要询问的似乎是生成粘贴图像的应用程序接受的任何格式。
  • @dementedhedgehog 我正在与之交互的应用程序是 Registry Ripper,它输出非标准文本并创建大量不需要的过多结果。所以我的方法是调用应用程序,读取标准输出,将数据放入上面分配的三个变量中,然后输出到 .csv 中。然而,第三个变量有许多换行符,不幸的是它们正在被 csv.writer 读取并输出到单独的单元格,如sample output 中所述。有没有办法在 .csv 的输出中保留换行符/回车符,以便我可以获得desired state
  • 是否有其他 .csv 模块可以执行上述操作?我的问题是否不清楚,是否缺乏赏金?自从我发布以来,上述问题一直困扰着我。我已经尝试了多个小时的解决方案,但我无法掌握(可能是因为我是编程新手)。
  • 您也可以编写自己的 csv 编写器。这很简单(如果您需要在值前添加一个空格,如下所示:“2\n3”)。我没有 excel,所以我无法测试 excel 成功导入的格式(无论如何它可能会因 excel 版本而异)。

标签: python-2.7 csv


【解决方案1】:

不是答案...但我想要代码格式。

import csv
x = ("1", "2\n3", "4")
f = csv.writer(open('foo', 'w'),
                   dialect=csv.excel,
                   delimiter='\t')
f.writerow(x)

产生这个:

$ less foo
1       "2
3"      4

那是“有效”制表符分隔的 csv.. 只是 excel 没有“正确”处理它。引号中的内容实际上是更多的实施问题,因为它不是标准化的格式。 23 周围多余的双引号有点烦人。

查看https://pypi.python.org/pypi/xlwt(pre xml excel 格式)或http://xlsxwriter.readthedocs.org/(xml excel 格式)以获取第三方库以直接编写 excel。

【讨论】:

    【解决方案2】:

    在 cmets 的指导下,我找到了答案。只需 excel 破坏格式(出于 cmets 中所述的原因)。但是,当在 LibreOffice 中打开时,格式会保留。

    cmets (Importing CSV with line breaks in Excel 2007) 中的建议线程有一个有目的的解决方法,包括引用实际的换行符与引用整个字符串,这就是我正在做的。

    【讨论】:

      【解决方案3】:

      这就是我解决这个问题的方法。

      输入数据:

      ('firstName.lastName@gmail.com', 'firstName', 'lastName', 'Address1', 'Address1
      Address2', 'IP1
      IP2
      IP3', 'PhoneNumber')
      

      所需的 CSV 格式:

      这里有一段 Python 代码可以得到相同的结果:

      try:
          cs.execute(sql)
          row = cs.fetchone()
          while row is not None:
              email = row[0]
              filename = '{0}.csv'.format(email)
              with open(filename, "w", encoding='utf-8-sig', newline='') as fp:
                  writer = csv.writer(fp)
                  writer.writerow(('REQUESTER EMAIL', 'FIRST NAME', 'LAST NAME', 'BILLING ADDRESSES', 'SHIPPING ADDRESSES', 'IP ADDRESSES', 'PHONE NUMBER'))
                  writer.writerow((
                      row[0],
                      row[1],
                      row[2],
                      row[3],
                      row[4],
                      row[5],
                      row[6],
                  ))
              row = cs.fetchone()
      finally:
          cs.close()
      ctx.close()
      

      看到这一行(#7):

      open(filename, "w", encoding='utf-8-sig', newline='')

      为 'utf-8-sig' 设置一个 unicode 就可以了。

      谢谢, 侯赛因·博拉

      【讨论】:

        【解决方案4】:

        您可以简单地使用 \n 来分隔多行单元格中的项目。只需确保整个单元格内容出现在双引号之间:

        f = open(filename, "w", encoding='utf-8')

        f.write('a,b,"c\nd",e\n')

        此示例在 csv 文件中写入一行,其中第三个单元格有 2 行 cd

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-06
          • 2019-12-15
          • 2013-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-26
          相关资源
          最近更新 更多