11

有没有办法将文本文件中的所有 CR 转换为 CRLF?

当我在 Windows 上从 Linux 服务器打开一个文本文件时,所有文本都显示在一行中,但实际上它是多行的。

我想在批处理文件中执行转换。

有人可以建议吗?

4

7 回答 7

16

只要存在不止一种系统和交换数据的冲动,线路分隔符和线路终结器就一直是系统之间兼容性摩擦的根源。Newline 上的维基百科文章对历史背景进行了不错的概述。并且,它针对这个问题提出了多种解决方案,专门用于 Unix 端或 Windows 端。

在 Unix (Linux) 端,查找名为unix2dos及其近亲的实用程序dos2unix. 这些都是常见的,可以作为商业 Unix 的一个组件,也可以作为开源工具。如果可用,它们是最好的答案,因为它们(通常,请参阅您的版本的手册页了解详细信息)对意外写入两个行尾的文件非常小心。在那种不幸的情况下,通过这两个实用程序通常会清理文件以保持内部一致。在没有这些方便的命令的情况下,可以使用许多本机实用程序来进行转换。tr例如,可以使用以下命令将 DOS CRLF 换行符转换为 Unix 换行符:

$ tr -d '\r' < inputfile > outputfile

但请注意,此命令假定所有行都由 CRLF(或 LFCR)终止,并且通过简单地从输入中删除每个 CR 字符来工作。任何裸露的 CR 字符都将丢失。

在 DOS 和 Windows 方面,它曾经很暗淡。的端口unix2dos并且dos2unix肯定存在,例如它们包含在更大的 Cygwin 工具中,这些工具在 Windows 机器上提供完整的 unix 仿真。但是很难找到仅使用内置功能的解决方案。

然而,现代 Windows(可能是从 Windows XP 开始)更好。在那里,内置的 FIND 命令对行终止符的选择比以前少了很多,并且可以用来进行从 Unix 行结尾到 DOS 结尾的所需转换。上面引用的 Wiki 页面给出了这个秘诀:

C:\...> TYPE filename.u | FIND "" /V >filename.txt

实验表明这也有效,但由于未知原因,它可能不会给出相同的结果:

C:\...> FIND "" /V <filename.u >filename.txt

在这两种情况下,您都会创建一个带有更改的行尾的文件副本。可能不建议就地更改文件。

我将提到另一种在纸上看起来总是很诱人的方法。当您使用 Samba 在 Linux 服务器上提供文件系统共享以供 Windows 挂载时,您可以为共享设置一个配置选项,以“文本模式”挂载它。以“文本模式”挂载的共享会自动转换行尾。如果它适合您,那可能是最干净的解决方案。两个系统都使用他们喜欢的文本文件格式,而且都不必大惊小怪。但仔细测试,这个解决方案充满了边缘情况和陷阱。最重要的是,不要期望文本模式文件系统挂载点上的二进制文件能够正确读取。他们经常会,但不一定总是。

于 2013-11-11T19:38:55.077 回答
7
type inputfile | find /v "" > outputfile

那应该这样做。type使用参数读取输入文件和管道输出以find匹配所有行并将它们输出到输出文件。在这个过程中,LF被转换为CRLF

于 2013-11-11T19:35:13.063 回答
2

如果我没记错的话,一种可能但相当麻烦的方法是使用CertUtil.exe自 Windows XP 以来本机包含的可执行文件。这是一个可能的脚本(让我们称之为conv-eol.bat;查看代码中的所有解释性rem注释):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_IFILE=%~1"  & rem // (input file; first command line argument)
set "_OFILE=%~2"  & rem // (output file; second command line argument)
set "_IEOL=0d"    & rem // (incoming line-breaks; `0d` or `0a`)
set "_OEOL=0d 0a" & rem // (outgoing line-breaks; `0d`, `0a`, `0d 0a`, ``)
set "_TFILE1=%TEMP%\%~n0_%RANDOM%.hex" & rem // (first temporary file)
set "_TFILE2=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (second temporary file)

rem // Verify input file:
< "%_IFILE%" rem/ || exit /B
rem // Convert input file to hexadecimal values (first temporary file):
CertUtil -f -encodehex "%_IFILE%" "%_TFILE1%" 4 > nul
rem // Write to second temporary file:
> "%_TFILE2%" (
    setlocal EnableDelayedExpansion
    rem // Read first temporary file line by line:
    for /F "usebackq delims=" %%L in ("!_TFILE1!") do (
        rem /* Store current line (hex. values), then replace line-breaks
        rem    using the given line-break codes and return result: */
        set "LINE=%%L" & echo(!LINE:%_IEOL%=%_OEOL%!
    )
    endlocal
)
rem // Verify output file:
> "%_OFILE%" rem/ || exit /B
rem // Convert second temporary file back to text into output file:
CertUtil -f -decodehex "%_TFILE2%" "%_OFILE%" 4 > nul
rem // Clean up temporary files:
del "%_TFILE1%" "%_TFILE2%"

endlocal
exit /B

将输入文件作为第一个命令行参数,将输出文件作为脚本的第二个参数提供(它们甚至可能相等):

conv-eol.bat "input-file.txt" "output-file.txt"

输入和输出换行符必须指定为十六进制字符代码,同时0d表示回车(CR)和0a换行(LF)字符。

下表说明了如何为不同的换行样式转换任务设置变量_IEOL_OEOL脚本顶部:

from       \       to||Mac (CR)             ||Unix/Linux (LF)      ||DOS/Windows (CR+LF)  
Mac (CR)             ||#####################||_IEOL=0d, _OEOL=0a   ||_IEOL=0d, _OEOL=0d 0a
Unix/Linux (LF)      ||_IEOL=0a, _OEOL=0d   ||#####################||_IEOL=0a, _OEOL=0d 0a
DOS/Windows (CR+LF)  ||_IEOL=0a, _OEOL=     ||_IEOL=0d, _OEOL=     ||#####################
于 2019-12-11T03:13:23.527 回答
1
cat file | perl -pe 's/\R/\n/g'
于 2014-05-14T14:15:23.370 回答
1

以下批处理片段可以解决问题:

del outputfile
for /f "delims=" %%x in (inputfile) do echo %%x>>outputfile

它的优点是不依赖于find程序,这是相当喜怒无常的(在我测试其他解决方案的某些机器上挂起或不起作用)。

于 2018-03-27T11:00:44.077 回答
0

在 Windows XP 及更早版本中,您只需在 Dos Edit(或 Windows Edit)中打开并保存文本文件即可将其转换为 CRLF。不幸的是,编辑程序在 Vista 中被删除了。

于 2016-09-23T15:59:54.903 回答
0

一种荒谬的方式。适用于以下场景:

  1. 每行末尾带有 CR 的文本文件。
  2. 在行尾带有重复的 CR 集的文本文件,后跟带有 CRLF 的空行。祝你好运!

在 Notepad++(免费应用程序)中打开文件并设置查看 -> 所有字符。

如果所有行都以 CR 结尾,则:

  1. 在 Microsoft Wordpad - NOT - Word 中打开并以 MSDOS 格式保存文件。ELSE IF 行以 CR 结尾,后跟以 CRLF 结尾的空行,然后
  2. 首先使用 Notepad++ 删除空行。转到编辑-> 行操作-> 删除空行并保存文件。
  3. 在 Microsoft 写字板中打开文件并以 MSDOS 格式保存。

万一

于 2018-02-21T07:14:27.530 回答