我在 Windows 上工作。我有一个 Python 文件来创建一个新的 CSV 文件,我使用记事本(甚至通过Microsoft 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)
Run Code Online (Sandbox Code Playgroud)
记事本中的结果文件:
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)
Run Code Online (Sandbox Code Playgroud)
回车是否\r有效?它的工作原理就像lineterminator=''在记事本中。但在 Excel 中,它的工作方式类似于 '\n'。
输出似乎没有实现回车。当我lineterminator用作:
w = csv.writer(l, delimiter='|', lineterminator='*\r*\n')
Run Code Online (Sandbox Code Playgroud)
记事本中的输出是:
fruit|quantityapple|5banana|7mango|8
Run Code Online (Sandbox Code Playgroud)
这在这里也很明显。
'\r'lineterminator在 writer()中是如何工作的?或者那里正在发生其他事情?
何时使用回车 (CR, \r) 与换行符 (LF, \n) 与两者 (CRLF, \r\n) 在 Windows、Mac 和 Linux 上的文本编辑器中显示新行:
'\r' 如何在 writer() 中的 lineterminator 中工作??
它在csv.writer(). 这真的不是 Python、CSV 或编写器的问题。这是操作系统的历史差异(实际上,更准确地说,它是特定于程序的差异)可以追溯到 1960 年代左右。
或者那里正在发生其他事情?
是的,就是这个。
您的记事本版本无法将回车符 ( \r)识别为用于显示新行的字符,因此不会在记事本中如此显示。其他文本编辑器,例如Sublime Text 3,即使在 Windows 上也可能会。
直到大约 2018 年左右,Windows 和记事本都需要一起回车 + 换行符 ( \r\n)来显示新行。将此与 Mac 和 Linux 形成对比,后者只需要.\n
解决方案是\r\n在 Windows 上\n用于换行,在 Mac 或 Linux 上单独用于换行。您还可以在查看或编辑文本文件时尝试使用不同的文本编辑器,例如 Sublime Text,或者升级您的 Windows 或记事本版本(如果可能的话),因为大约在 2018 年左右, Windows 记事本开始接受\r单独作为有效的旧版本 - Mac 风格的换行符。
(来自 OP 在此答案下的评论):
那为什么要给'\r\n'???
当程序员编写程序时,程序员可以让程序做程序员想让程序做的任何事情。当Windows程序员做Windows和记事本,他们决定把节目做什么,如果它有一个\r,没有什么,如果它有一个\n,并做了新的生产线,如果它得到了\r\n 起来。就这么简单。该程序完全按照程序员的要求执行,因为他们决定这就是他们希望程序运行的方式。因此,如果您想在 Windows 的旧版(2018 年之前)记事本中添加新行,则必须执行程序员要求您执行的操作才能获得它。\r\n是吗。
这可以追溯到电传打字机的时代(阅读此处的“历史”和“表现”部分),以及有关“电传打字机”/“电传打字机”/“电传打字机或 TTY 机器”的页面:
打字机或机电打印机可以在纸上打印字符,并执行诸如将马车移回同一行的左边距(回车)、前进到下一行的同一列(换行)等操作.
(来源;强调添加)
电传打字机上的机械回车按钮(\r现在在计算机上)的意思是:“将回车(打印头)返回到行首”(意思是:页面的最左侧),换行机械机构位于电传打字机(\n现在在电脑上)的意思是:“把纸卷起来一行,这样我们就可以在下一行打字了。” 如果没有机械换行 ( \n) 动作,\r仅回车 ( ) 就会将机械打印头移动到页面的最左侧,并使您在已经输入的单词的顶部重新输入!并且没有回车机械动作(\r在电脑上),换行机械动作(\n) 单独会导致您只在页面上每个新行的最右侧的最后一列中键入,永远无法再次将打印头返回到页面的左侧!在机电式电传打字机上,它们都必须使用:回车会将打印头带回页面的左侧,换行操作会将打印头向下移动到下一行。因此,据推测,Windows程序员认为这是合乎逻辑的,以保持这一传统活着,他们决定需要双方一\r\n 起来建立一个计算机上新的生产线,因为这是它必须对机电电传打字机传统做。
阅读下文了解详情。
我对正在发生的事情有一些想法,但让我们来看看。我相信我们有两个问题需要回答:
\r实际存储到文件中?\r,如果没有,为什么不呢?所以,对于#1。让我们在 Linux Ubuntu 20.04 (Focal Fossa)上测试一下:
这个程序:
#!/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)
Run Code Online (Sandbox Code Playgroud)
生成此文件:d:\lineter.csv。如果我在Sublime Text 3 文本编辑器中打开它,我会看到:
#!/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)
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。让我们看看hexdump命令行中的字符:
hexdump -c显示\r人物,果然!
fruit|quantity
apple|5
banana|7
mango|8
Run Code Online (Sandbox Code Playgroud)
您也可以使用hexdump -C以十六进制显示字符,再次,我\r将文件中的 视为十六进制0d字符,这是正确的。
好的,所以我在 Linux 中的VirtualBox虚拟机中启动了 Windows 10 Professional ,并在记事本中打开了相同的文件,并且....它也可以工作!看截图:
但是,请注意我圈出的“Macintosh (CR)”部分。我正在运行最新版本的 Windows 10 专业版。我敢打赌您使用的是没有此修复程序的旧版记事本,您不会在这里说。 这是因为 33 年来记事本没有处理回车,或者\r作为有效的行尾,所以它不会这样显示。请参阅此处:Windows 记事本在 33 年后修复:现在它终于可以处理 Unix、Mac OS 行尾了。
由于可追溯到电传打字机和摩尔斯电码的历史差异(阅读此处的“历史”和“表示”部分),不同的系统决定让它们的文本编辑器以不同的方式处理行尾。从上面的文章(强调):
记事本以前只能识别 Windows 行尾(EOL) 字符,特别是回车符 (CR, \r, 0x0d) 和换行符 (LF, \n, 0x0a) 在一起。
对于老式 Mac OS,EOL 字符只是 Carriage Return (CR, \r, 0x0d)而对于 Linux/Unix,它只是 Line Feed (LF, \n, 0x0a)。自 Mac OS X 以来,现代 macOS 遵循 Unix 约定。
所以,我们这里有以下内容在文本编辑器中显示为换行符:
\r仅CR ( )\r\n)\n仅LF ( )\n仅LF ( )因此,对于的Windows,只是坚持始终使用\r\n一个换行符,并为Mac或Linux操作系统,只是坚持始终使用\n一个换行符,除非你要保证老派(即预2019 :))Windows兼容性您的文件,在这种情况下,您也应该使用\r\n换行符。
请注意,对于 Sublime Text 3,我只是在Preferences 中搜索了首选项?设置并找到此设置:
$ 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
Run Code Online (Sandbox Code Playgroud)
因此,要在运行 Sublime Text 的任何操作系统上使用约定,默认值是“系统”。但是,要在 Sublime Text 中编辑和保存文件时强制使用 'windows' (CRLF) 行结尾,请使用以下命令:
// 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",
Run Code Online (Sandbox Code Playgroud)
并强制使用 Unix(Mac 和 Linux)LF-only 行结束设置,请使用以下命令:
"default_line_ending": "windows",
Run Code Online (Sandbox Code Playgroud)
在记事本编辑器中,我找不到要配置的此类设置。这是一个简单的编辑器,仅适用于 Windows 行尾的 33 年。