如何找出文本文件中的行尾?

Posted

技术标签:

【中文标题】如何找出文本文件中的行尾?【英文标题】:How to find out line-endings in a text file? 【发布时间】:2011-04-03 22:56:33 【问题描述】:

我正在尝试在 bash 中使用某些东西来向我显示打印而不是解释的文件中的行尾。该文件是来自 SSIS/SQL Server 的转储文件,正在被 Linux 机器读取以进行处理。

vilessmore等内部有开关吗?

除了查看行尾,我还需要知道它是什么类型的行尾(CRLFLF)。我怎么知道呢?

【问题讨论】:

一般提示:如果您知道可以使用哪个 *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 才能获得dos2unixunix2dos 其实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 我相信它会显示 \n 或 \r\n。 在“物有所值”类别中,您可以通过发出 grep --regex="^M" grep 获取 Dos 样式的 CRLF,其中 ^M 是 CTRL+V CTRL+M。您可以通过用 sed 命令替换它们来删除它们。这与 dos2unix 基本相同 在 vim 中::set fileformat 将报告 unixdos 中的哪一个 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 序列将在每个输出行的末尾显示为^Mcat -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 -kdosunix -ih

详情如下。


试试file -k

短版:file -k somefile.txt会告诉你。

它将为 DOS/Windows 行结尾输出 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

【讨论】:

以上是关于如何找出文本文件中的行尾?的主要内容,如果未能解决你的问题,请参考以下文章

如何找出两个文本文件中有相同字段的行

如何找出两个文本文件中有相同字段的行

利用cat命令显示文本内容时,要在Linux每行的行尾显示$符号,该命令应带有啥?

在文本每一行的行首和行尾都插入特定的相同字符或文本

vim文本编辑

C++ 从文本文件检查操作系统