如何找出文本文件中的行尾?
Posted
技术标签:
【中文标题】如何找出文本文件中的行尾?【英文标题】:How to find out line-endings in a text file? 【发布时间】:2011-04-03 22:56:33 【问题描述】:我正在尝试在 bash 中使用某些东西来向我显示打印而不是解释的文件中的行尾。该文件是来自 SSIS/SQL Server 的转储文件,正在被 Linux 机器读取以进行处理。
vi
、less
、more
等内部有开关吗?
除了查看行尾,我还需要知道它是什么类型的行尾(CRLF
或LF
)。我怎么知道呢?
【问题讨论】:
一般提示:如果您知道可以使用哪个 *nix/cygwin 命令,您可以随时查看其联机帮助页来搜索可能为您提供所需功能的开关。例如,man less
.
【参考方案1】:
您可以使用file
实用程序来指示行尾的类型。
Unix:
$ file testfile1.txt
testfile.txt: ASCII text
“DOS”:
$ file testfile2.txt
testfile2.txt: ASCII text, with CRLF line terminators
从“DOS”转换为 Unix:
$ dos2unix testfile2.txt
从 Unix 转换为“DOS”:
$ unix2dos testfile1.txt
转换已转换的文件无效,因此可以安全地盲目运行(即不先测试格式),尽管通常的免责声明一如既往地适用。
【讨论】:
这些现在有时分别命名为“fromdos”和“todos”(在 Ubuntu 10.4+ 中就是这种情况) @JessChadwick:是的,但前提是您使用sudo apt-get install tofrodos
显式安装tofrodos
包 - 就像您必须运行sudo apt-get install dos2unix
才能获得dos2unix
和unix2dos
。
其实dos2unix不能做所有的工作,我认为***.com/questions/23828554/dos2unix-doesnt-convert-m给出了最好的答案
@nathan:dos2unix
失败的原因是什么?该问题的 OP 仅模糊地描述了该问题。
@DennisWilliamson file 命令在 dos2unix 命令之前和之后得到相同的输出:xxx.c C 源代码,ASCII 文本,带有 CR,LF 行终止符。我发现这个 c 文件在喜欢 xxxxxxx ^M xxxxxxx 的行中间有 ^M【参考方案2】:
Ubuntu 14.04:
简单的cat -e <filename>
工作得很好。
这会将 Unix 行尾(\n
或 LF)显示为 $
,将 Windows 行尾(\r\n
或 CRLF)显示为 ^M$
。
【讨论】:
也适用于 OSX。很好的解决方案。简单并且对我有用,而接受的答案却没有。 (注意:不是.txt
文件)
M$ 的展示是在抨击复活节/windows 吗?
不适用于 Solaris,但 man 说它应该可以工作
@TomM 没有。 ^M$
中的插入符号将其反转为 Microsoft 信徒的复活节彩蛋。
我发现必须使用cat -vE <filename>
才能看到\r
字符(显示为^M
)和\n
字符(显示为$
)。这是在 Linux 上使用 GNU cat
。【参考方案3】:
在vi
...
:set list
查看行尾。
:set nolist
恢复正常。
虽然我认为您在vi
中看不到\n
或\r\n
,但您可以通过查看它是哪种类型的文件(UNIX、DOS 等)来推断它具有哪些行结尾。 .
:set ff
或者,您可以从bash
使用od -t c <filename>
或仅使用od -c <filename>
来显示回报。
【讨论】:
不幸的是,我认为 vi 不能显示那些特定的字符。您可以尝试 od -c:set fileformat
将报告 unix
或 dos
中的哪一个 vim 认为文件的行结尾在。您可以通过 :set fileformat=unix
更改它。
在启动 vi/vim 时使用 -b 标志,然后使用 :set list 查看 CR (^M) 和 LF ($) 结尾。
@RyanBerger - 看起来你缺少 -t。应该是od -t c file/path
,但感谢新程序。效果很好!【参考方案4】:
在 bash shell 中,尝试cat -v <filename>
。这应该显示 windows 文件的回车。
(这在 Windows XP 上通过 Cygwin 在 rxvt 中对我有用)。
编者注:cat -v
可视化 \r
(CR) 字符。作为^M
。因此,行尾\r\n
序列将在每个输出行的末尾显示为^M
。 cat -e
将另外可视化\n
,即$
。 (cat -et
还会将制表符可视化为^I
。)
【讨论】:
@ChrisK:试试echo -e 'abc\ndef\r\n' | cat -v
,你应该会在“def”之后看到^M
。
我想看看文件是否有 ^M(Windows/DOS EOL) 并且只有 cat -v 向我展示了这一点。为此 +1
^M = DOS/Windows 风格
更正:因此,行尾 \r\n 序列将显示为 ^M$【参考方案5】:
尝试file
,然后是file -k
,然后是dos2unix -ih
file
通常就足够了。但对于棘手的情况,请尝试 file -k
或 dosunix -ih
。
详情如下。
试试file -k
短版:file -k somefile.txt
会告诉你。
with CRLF line endings
。
它将为 MAC 行结尾输出 with CR line endings
。
对于 Linux/Unix 行“LF”,它只会输出text
。 (因此,如果它没有明确提及任何类型的 line endings
,那么这隐含的意思是:“LF 行结尾”。)
长版见下文。
现实世界的例子:证书编码
我有时必须检查 PEM 证书文件。
普通file
的问题在于:有时它试图变得太聪明/太具体。
让我们做个小测验:我有一些文件。其中一个文件具有不同的行尾。哪一个?
(顺便说一句:这是我典型的“证书工作”目录之一。)
让我们试试普通的file
:
$ file -- *
0.example.end.cer: PEM certificate
0.example.end.key: PEM RSA private key
1.example.int.cer: PEM certificate
2.example.root.cer: PEM certificate
example.opensslconfig.ini: ASCII text
example.req: PEM certificate request
嗯。它没有告诉我行尾。我已经知道那些是证书文件。我不需要“文件”来告诉我。
你还能尝试什么?
您可以尝试使用 dos2unix
和 --info
开关,如下所示:
$ dos2unix --info -- *
37 0 0 no_bom text 0.example.end.cer
0 27 0 no_bom text 0.example.end.key
0 28 0 no_bom text 1.example.int.cer
0 25 0 no_bom text 2.example.root.cer
0 35 0 no_bom text example.opensslconfig.ini
0 19 0 no_bom text example.req
所以这告诉你:是的,“0.example.end.cer”一定是个奇怪的人。但是有什么样的行尾呢? 你是否熟悉 dos2unix 输出格式? (我没有。)
但幸运的是file
中有--keep-going
(或简称-k
)选项:
$ file --keep-going -- *
0.example.end.cer: PEM certificate\012- , ASCII text, with CRLF line terminators\012- data
0.example.end.key: PEM RSA private key\012- , ASCII text\012- data
1.example.int.cer: PEM certificate\012- , ASCII text\012- data
2.example.root.cer: PEM certificate\012- , ASCII text\012- data
example.opensslconfig.ini: ASCII text\012- data
example.req: PEM certificate request\012- , ASCII text\012- data
太棒了!现在我们知道我们的奇数文件有 DOS (CRLF
) 行结尾。 (并且其他文件具有 Unix (LF
) 行结尾。这在此输出中并不明确。它是隐含的。这正是 file
期望的“常规”文本文件的方式。)
(如果你想分享我的助记词:“L”代表“Linux”和“LF”。)
现在让我们转换罪魁祸首再试一次:
$ dos2unix -- 0.example.end.cer
$ file --keep-going -- *
0.example.end.cer: PEM certificate\012- , ASCII text\012- data
0.example.end.key: PEM RSA private key\012- , ASCII text\012- data
1.example.int.cer: PEM certificate\012- , ASCII text\012- data
2.example.root.cer: PEM certificate\012- , ASCII text\012- data
example.opensslconfig.ini: ASCII text\012- data
example.req: PEM certificate request\012- , ASCII text\012- data
很好。现在所有证书都有 Unix 行结尾。
试试dos2unix -ih
我在写上面的例子时并不知道这一点,但是:
事实上,如果你像这样使用-ih
(--info=h
的缩写),dos2unix 会给你一个标题行:
$ dos2unix -ih -- *
DOS UNIX MAC BOM TXTBIN FILE
0 37 0 no_bom text 0.example.end.cer
0 27 0 no_bom text 0.example.end.key
0 28 0 no_bom text 1.example.int.cer
0 25 0 no_bom text 2.example.root.cer
0 35 0 no_bom text example.opensslconfig.ini
0 19 0 no_bom text example.req
还有一个“实际上”的时刻:标题格式真的很容易记住:这里有两个助记符:
-
它是 DUMB(从左到右:d 代表 Dos,u 代表 Unix,m 代表 Mac,b 代表 BOM)。
另外:“DUM”只是 D、U 和 M 的字母顺序。
进一步阅读
man file
man dos2unix
***:Newline
【讨论】:
它在 MinTTY 的 Windows 上生成如下输出:Accounts.java: Java source, ASCII text\012-
@standalone:有趣。我读过关于一个名为“igncr”的选项的奇怪东西——你所说的听起来像那样。但无法重现您所描述的内容。 (我尝试了 Git-for-Windows 附带的 Bash inside mintty,“git version 2.24.0.windows.1”。)
嗯,我在 git-for-windows 附带的 mintty 中也试过 file -k Accounts.java
,但我的版本是 git version 2.21.0.windows.1
我的工作解决方案是cat -e file_to_test
【参考方案6】:
要将 CR 显示为 ^M
in less 使用 less -u
或在 less 打开时键入 -u。
man less
说:
-u or --underline-special Causes backspaces and carriage returns to be treated as print- able characters; that is, they are sent to the terminal when they appear in the input.
【讨论】:
请澄清你的答案。【参考方案7】:您可以使用xxd
显示文件的十六进制转储,并搜索“0d0a”或“0a”字符。
您可以按照@warriorpostman 的建议使用cat -v <filename>
。
【讨论】:
它适用于 cat v 8.23。 Unix 行尾不会打印任何额外的信息,但 DOS 行尾会打印一个“^M”。 这一定是我在 8.21 中遇到的问题,因为我使用的是 unix 行尾。【参考方案8】:您可以使用命令todos filename
转换为 DOS 结尾,使用命令fromdos filename
转换为 UNIX 行结尾。要在 Ubuntu 上安装该软件包,请键入 sudo apt-get install tofrodos
。
【讨论】:
【参考方案9】:您可以使用vim -b filename
以二进制模式编辑文件,这将显示 ^M 字符作为回车符,并且新行表示存在 LF,表示 Windows CRLF 行结尾。 LF 我的意思是\n
,CR 我的意思是\r
。请注意,当您使用 -b 选项时,默认情况下文件将始终在 UNIX 模式下编辑,如状态行中的 [unix]
所示,这意味着如果您添加新行,它们将以 LF 结尾,而不是 CRLF。如果您在带有 CRLF 行结尾的文件上使用不带 -b 的普通 vim,您应该会在状态行中看到 [dos]
,并且插入的行将以 CRLF 作为行尾。 fileformats
设置的 vim 文档解释了复杂性。
另外,我没有足够的分数来评论 Notepad++ 的答案,但如果您在 Windows 上使用 Notepad++,请使用 View / Show Symbol / Show End of Line 菜单来显示 CR 和 LF。在这种情况下,显示的是 LF,而对于 vim,LF 由一个新行表示。
【讨论】:
【参考方案10】:我将我的输出转储到一个文本文件中。然后我在记事本++中打开它,然后单击显示所有字符按钮。不是很优雅,但很有效。
【讨论】:
这个问题被标记为 Linux,我认为 notepad++ 不适合 linux。不过,这应该适用于 Windows。【参考方案11】:Vim - 总是将 Windows 换行显示为^M
如果您希望始终将 vim 中的 Windows 换行符显示为 ^M
,您可以将此行添加到您的 .vimrc
:
set ffs=unix
这将使 vim 将您打开的每个文件解释为 unix 文件。由于 unix 文件将\n
作为换行符,因此带有\r\n
换行符的windows 文件仍将正确呈现(感谢\n
),但文件末尾将有^M
(即vim 如何渲染\r
字符)。
Vim - 有时会显示 Windows 换行符
如果您只想针对每个文件进行设置,可以在编辑给定文件时使用:e ++ff=unix
。
Vim - 总是显示文件类型(unix
vs dos
)
如果您希望 vim 的底线始终显示您正在编辑的文件类型(并且您没有强制将文件类型设置为 unix),您可以使用 set statusline+=\ %&fileencoding?&fileencoding:&encoding
添加到您的statusline
。
下面提供了我的完整状态栏。只需将其添加到您的.vimrc
。
" Make statusline stay, otherwise alerts will hide it
set laststatus=2
set statusline=
set statusline+=%#PmenuSel#
set statusline+=%#LineNr#
" This says 'show filename and parent dir'
set statusline+=%expand('%:p:h:t')/%t
" This says 'show filename as would be read from the cwd'
" set statusline+=\ %f
set statusline+=%m\
set statusline+=%=
set statusline+=%#CursorColumn#
set statusline+=\ %y
set statusline+=\ %&fileencoding?&fileencoding:&encoding
set statusline+=\[%&fileformat\]
set statusline+=\ %p%%
set statusline+=\ %l:%c
set statusline+=\
它会像这样渲染
.vim/vimrc\ [vim] utf-8[unix] 77% 315:6
在文件的底部
Vim - 有时显示文件类型(unix
vs dos
)
如果您只想查看您拥有的文件类型,您可以使用:set fileformat
(如果您强制设置文件类型,这将不起作用)。对于 unix 文件,它将返回 unix
,对于 Windows,它将返回 dos
。
【讨论】:
以上是关于如何找出文本文件中的行尾?的主要内容,如果未能解决你的问题,请参考以下文章