我试图在 bash 中使用一些东西来向我展示打印而不是解释的文件中的行尾。该文件是来自 SSIS/SQL Server 的转储文件,正在被 Linux 机器读取以进行处理。
vi、less、more 等中是否有任何开关?
除了查看行尾,我还需要知道它是什么类型的行尾(CRLF 或 LF)。我怎么知道呢?
man less
。
您可以使用 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
转换已转换的文件没有任何效果,因此可以安全地盲目运行(即无需先测试格式),尽管通常的免责声明一如既往地适用。
Ubuntu 14.04:
简单的 cat -e <filename>
工作得很好。
这会将 Unix 行尾(\n
或 LF)显示为 $
,将 Windows 行尾(\r\n
或 CRLF)显示为 ^M$
。
.txt
文件)
^M$
中的插入符号将其反转为 Microsoft 信徒的复活节彩蛋。
cat -vE <filename>
才能看到 \r
个字符(显示为 ^M
)和 \n
个字符(显示为 $
)。这是在 Linux 上使用 GNU cat
。
在 vi
...
:set list
查看行尾。
:set nolist
恢复正常。
虽然我认为您在 vi
中看不到 \n
或 \r\n
,但您可以通过查看它是哪种类型的文件(UNIX、DOS 等)来推断它具有哪些行结尾...
:set ff
或者,您可以从 bash
使用 od -t c <filename>
或仅使用 od -c <filename>
来显示回报。
:set fileformat
将报告 unix
或 dos
中的哪一个 vim 认为文件的行尾在其中。您可以通过 :set fileformat=unix
更改它。
od -t c file/path
,但感谢新程序。工作得很好!
在 bash shell 中,尝试 cat -v <filename>
。这应该显示 windows 文件的回车。
(这在 Windows XP 上通过 Cygwin 在 rxvt 中对我有用)。
编者注:cat -v
可视化 \r
(CR) 字符。作为^M
。因此,行尾 \r\n
序列将在每个输出行的末尾显示为 ^M
。 cat -e
还会将 \n
可视化,即 $
。 (cat -et
将另外将标签字符可视化为 ^I
。)
echo -e 'abc\ndef\r\n' | cat -v
,你应该在“def”之后看到一个 ^M
。
尝试文件,然后是文件 -k,然后是 dos2unix -ih
file
通常就足够了。但对于棘手的情况,请尝试 file -k
或 dosunix -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
维基百科:换行
Accounts.java: Java source, ASCII text\012-
file -k Accounts.java
,但我的版本是 git version 2.21.0.windows.1
cat -e file_to_test
要在 less 中将 CR 显示为 ^M
,请使用 less -u
或在 less 打开后键入 -u。
man less
说:
-u 或 --underline-special 将退格和回车视为可打印字符;也就是说,当它们出现在输入中时,它们被发送到终端。
您可以使用 xxd
显示文件的十六进制转储,并搜索“0d0a”或“0a”字符。
您可以按照@warriorpostman 的建议使用 cat -v <filename>
。
您可以使用命令 todos filename
转换为 DOS 结尾,使用命令 fromdos filename
转换为 UNIX 行结尾。要在 Ubuntu 上安装软件包,请输入 sudo apt-get install tofrodos
。
您可以使用 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 由一个新行表示。
我将输出转储到文本文件中。然后我在记事本++中打开它,然后单击显示所有字符按钮。不是很优雅,但它有效。
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
。
sudo apt-get install tofrodos
显式安装tofrodos
软件包 - 就像您必须运行sudo apt-get install dos2unix
才能获得dos2unix
和unix2dos
。dos2unix
失败的原因是什么?该问题的OP仅模糊地描述了该问题。