ChatGPT解决这个技术问题 Extra ChatGPT

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

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

vi、less、more 等中是否有任何开关?

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

一般提示:如果您知道可以使用哪个 *nix/cygwin 命令,您可以随时查看其联机帮助页以搜索可能为您提供所需功能的开关。例如,man less

D
Dennis Williamson

您可以使用 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 无法完成所有工作,我认为 stackoverflow.com/questions/23828554/dos2unix-doesnt-convert-m 给出了最佳答案
@nathan:dos2unix 失败的原因是什么?该问题的OP仅模糊地描述了该问题。
@DennisWilliamson 在 dos2unix 命令之前和之后的文件命令得到相同的输出:xxx.c C 源代码,ASCII 文本,带有 CR,LF 行终止符。我发现这个 c 文件的中间有 ^M 喜欢 xxxxxxx ^M xxxxxxx
B
Bennett McElwee

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
E
Engineero

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,但感谢新程序。工作得很好!
m
mklement0

在 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$
S
StackzOfZtuff

尝试文件,然后是文件 -k,然后是 dos2unix -ih

file 通常就足够了。但对于棘手的情况,请尝试 file -kdosunix -ih

详情如下。

试试文件 -k

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

对于 DOS/Windows 行结尾,它将以 CRLF 行结尾输出。

它将以 CR 行结尾为 MAC 行结尾输出。

对于 Linux/Unix 行“LF”,它只会输出文本。 (因此,如果它没有明确提到任何类型的行尾,那么这隐含的意思是:“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

嗯。它没有告诉我行尾。而且我已经知道那些是证书文件。我不需要“文件”来告诉我。

一些网络设备对证书文件的编码方式非常非常挑剔。这就是为什么我需要知道。

你还能尝试什么?

您可以使用 --info 开关尝试 dos2unix,如下所示:

$ 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 的字母顺序。

进一步阅读

人文件

人dos2unix

维基百科:换行


它在 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
C
Captain Man

要在 less 中将 CR 显示为 ^M,请使用 less -u 或在 less 打开后键入 -u

man less 说:

-u 或 --underline-special 将退格和回车视为可打印字符;也就是说,当它们出现在输入中时,它们被发送到终端。


请澄清你的答案。
R
Rich

您可以使用 xxd 显示文件的十六进制转储,并搜索“0d0a”或“0a”字符。

您可以按照@warriorpostman 的建议使用 cat -v <filename>


它适用于 cat v 8.23。 Unix 行结尾不会打印任何额外信息,但 DOS 行结尾会打印“^M”。
这一定是我在 8.21 中遇到的问题,因为我使用的是 unix 行尾。
Z
Zorayr

您可以使用命令 todos filename 转换为 DOS 结尾,使用命令 fromdos filename 转换为 UNIX 行结尾。要在 Ubuntu 上安装软件包,请输入 sudo apt-get install tofrodos


s
smalers

您可以使用 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 由一个新行表示。


D
Diego

我将输出转储到文本文件中。然后我在记事本++中打开它,然后单击显示所有字符按钮。不是很优雅,但它有效。


这个问题被标记为 Linux,我认为 notepad++ 不适合 linux。不过,这应该适用于 Windows。
j
jeremysprofile

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