python - '\r'在Python `lineterminator`中不能作为 `csv.writer()`

标签 python windows csv writer

我在Windows上工作。我有一个Python文件可创建一个新的CSV文件,并使用记事本(甚至通过Ms Excel)查看该文件。

import csv
data=[['fruit','quantity'],['apple',5],['banana',7],['mango',8]]
with open('d:\lineter.csv','w') as l:
    w=csv.writer(l,delimiter='|',lineterminator='\r')
    w.writerows(data)
记事本中的结果文件:
fruit|quantityapple|5banana|7mango|8

我的疑问是,回车\r是否有效???它的工作方式类似于记事本中的lineterminator=''。但是在excel中,它的工作方式类似于'\n'
输出似乎未实现回车。当我使用lineterminator作为:
w=csv.writer(l,delimiter='|',lineterminator='*\r*\n')
记事本中的输出为:
fruit|quantity**
apple|5**
banana|7**
mango|8**
这在这里也很明显。
谁能告诉我'\r'在writer()的换行符中如何工作?
还是那里发生了其他事情?

最佳答案

简短的答案:
何时使用回车(CR,\r)vs换行(LF,\n)vs两者(CRLF,\r\n)来使新行出现在Windows,Mac和Linux上的文本编辑器中:

Can anyone tell me how '\r' works in lineterminator in writer()?


它在csv.writer()中可以正常工作。这确实不是Python,CSV或编写器问题。这是操作系统的历史差异(实际上,更确切地说是program-specific difference)可以追溯到1960年代左右。

Or is there any other thing happening there?


是的,这是一个。
您的记事本版本无法将回车(\r)识别为用于显示新行的字符,因此不会在记事本中显示该字符。其他文本编辑器,例如Sublime Text 3,即使在Windows上也可能如此。
直到大约2018年左右,Windows和记事本都需要使用回车+ LineFeed(\r\n)来显示新行。与此相比,Mac和Linux仅需要\n
解决方案是在Windows上将\r\n用于换行,在Mac或Linux上仅将\n用于换行。您还可以在查看或编辑文本文件时尝试使用其他文本编辑器(例如Sublime Text),或者在可能的情况下升级Windows或Notepad的版本,因为somewhere around the year 2018 Windows记事本开始接受\r作为有效的旧Mac风格新行字符。
(摘自OP在此答案下的评论):

Then why to give '\r\n'???


当程序员编写程序时,程序员可以使程序执行程序员希望程序执行的任何操作。当Windows程序员制作Windows和记事本时,他们决定使该程序如果带有\r不做任何事情,如果它带有\n不做任何事情,如果它带有\r\n 一起做新行。就这么简单。该程序完全按照程序员的指示进行操作,因为他们决定了这就是他们希望程序工作的方式。因此,如果您想在Windows的较旧(2018之前)版本的Notepad中添加新行,则必须执行程序员要求您执行的操作才能获得它。 \r\n是它。
这可以追溯到teletypewriters (read the "History" and "Representation" sections here)this page about "teleprinters"/"teletypewriters"/"teletype or TTY machines"的时代:

A typewriter or electromechanical printer can print characters on paper, and execute operations such as move the carriage back to the left margin of the same line (carriage return), advance to the same column of the next line (line feed), and so on.
(source; emphasis added)


电传打字机上的机械托架返回按钮(现在在计算机上为\r)表示:“将托架(打印头)返回到行的开头”(意味着:页面的最左侧),以及换行机械机构在电传打字机上(现在在计算机上为\n)表示:“将纸张向上滚动一行,以便我们现在可以在下一行上键入内容。”如果没有机械换行(\n) Action ,仅回车键(\r)会将机械打印头移到页面的最左侧,并使您在已经键入的单词上再次右击!如果没有回车机械 Action (在计算机上为\r),则仅靠换行机械 Action (\n)将导致您仅在页面上每行的最右边输入最后一列,而无法返回再次将打印头打印到页面左侧!在机电式电传打字机上,必须同时使用:回车将使打印头回到页面左侧,并且换行操作会将打印头向下移动到下一行。 因此,想必Windows程序员认为保持这一传统是合乎逻辑的,因此他们决定要求同时使用\r\n在计算机上创建新行,因为这是传统上必须在机电式电传打字机上完成的方式
请阅读下面的详细信息。
细节:
我对正在发生的事情有一些想法,但让我们看一下。我相信我们有两个问题要回答:
  • \r是否实际存储在文件中?
  • 记事本是否实际上显示\r,如果没有显示,为什么呢?

  • 因此,对于#1。让我们在Linux Ubuntu 20.04上对其进行测试:
    该程序:
    #!/usr/bin/python3
    
    import csv
    data=[['fruit','quantity'],['apple',5],['banana',7],['mango',8]]
    with open('d:\lineter.csv','w') as l:
        w=csv.writer(l,delimiter='|',lineterminator='\r')
        w.writerows(data)
    
    产生以下文件: d:\lineter.csv 。如果在Sublime Text 3 text editor中打开它,则会看到:
    fruit|quantity
    apple|5
    banana|7
    mango|8
    
    到目前为止,一切都很好。让我们在命令行中查看带有hexdump的字符:hexdump -c显示\r字符,果然!
    $ hexdump -c d\:\\lineter.csv 
    0000000   f   r   u   i   t   |   q   u   a   n   t   i   t   y  \r   a
    0000010   p   p   l   e   |   5  \r   b   a   n   a   n   a   |   7  \r
    0000020   m   a   n   g   o   |   8  \r                                
    0000028
    
    您还可以使用hexdump -C来以十六进制显示字符,同样,我将文件中的\r视为十六进制0d字符,这是正确的。
    好的,所以我在Linux的Virtual Box虚拟机中启动Windows 10 Professional,并在记事本中打开相同的文件,并且...也可以使用!看截图:
    enter image description here
    但是,请注意我圈出的部分是“Macintosh(CR)”。我正在运行Windows 10专业版的最新版本。 我敢打赌,您使用的是旧版本的记事本,但没有此修复程序,因此您不会在这里说。 这是因为33年来,记事本没有将回车符或\r作为有效的行尾处理,因此它不会像这样显示。看到这里:Windows Notepad fixed after 33 years: Now it finally handles Unix, Mac OS line endings
    由于使用historical differences dating back to teletypewriters and morse code(请在此处阅读“历史记录”和“表示形式”部分),不同的系统决定让其文本编辑器以不同的方式对待行尾。从article just above(添加了重点):

    Notepad previously recognized only the Windows End of Line (EOL) characters, specifically Carriage Return (CR, \r, 0x0d) and Line Feed (LF, \n, 0x0a) together.

    For old-school Mac OS, the EOL character is just Carriage Return (CR, \r, 0x0d) and for Linux/Unix it's just Line Feed (LF, \n, 0x0a). Modern macOS, since Mac OS X, follows the Unix convention.


    因此,我们在文本编辑器中将以下内容显示为换行符:
  • 老式Mac: CR(\r)仅
  • Windows记事本,直到〜2018年: CR和LF一起使用(\r\n)
  • Linux:仅 LF(\n)
  • 现代Mac:仅LF(\n)
  • 现代Windows记事本(〜2018年及更高版本):以上任何情况。

  • 因此,对于 Windows ,仅坚持使用\r\n进行换行,对于 Mac或Linux ,仅坚持使用\n进行换行,除非您试图保证使用过时的字体(即:pre- 2019 :))文件的Windows兼容性,在这种情况下,您也应该使用\r\n作为换行符。

    注意,对于Sublime Text 3,我只是在“首选项->设置”中搜索了首选项,并找到了此设置:
        // Determines what character(s) are used to terminate each line in new files.
        // Valid values are 'system' (whatever the OS uses), 'windows' (CRLF) and
        // 'unix' (LF only).
        "default_line_ending": "system",
    
    因此,要将约定用于正在运行Sublime Text的任何操作系统,默认值为“system”。要在“Sublime Text”中编辑和保存文件时强制“windows”(CRLF)行尾,请使用以下命令:
    "default_line_ending": "windows",
    
    并强制unix(Mac和Linux)仅LF的行结束设置,请使用以下命令:
    "default_line_ending": "unix",
    
    在记事本编辑器上,我找不到要配置的此类设置。它是一个简单的编辑器,仅适用于Windows行尾33年。
    补充阅读:
  • https://en.wikipedia.org/wiki/Teleprinter
  • https://en.wikipedia.org/wiki/Newline#History
  • Is a new line = \n OR \r\n?
  • Why does Windows use CR LF?
  • 关于python - '\r'在Python `lineterminator`中不能作为 `csv.writer()`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64393520/

    相关文章:

    通过命令行发送命令的Python代码

    database - 如何将社交网络关系 csv(列表字典)文件导入 neo4j 图形数据库?

    java - 在java中为每一行存储制表符分隔的CSV文件中的变量

    php - Woocommerce 插件 - 更新库存

    python - 退出对话框时不处理关闭事件

    python - 使用 Python xml.sax 打开命名空间模式

    Python Sqlite 一次插入一个数字字符串

    python - 为什么我收到错误 -"re.error: multiple repeat at position 2"

    c++ - 检查文件是否在 C++ 中是只读的

    windows - 在 Windows 中查看和/或编辑 .cblite 数据库?