使用CMD将所有CR转换为文本文件中的CRLF

时间:2013-11-11 18:08:36

标签: batch-file cmd newline

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

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

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

有人可以提出建议吗?

7 个答案:

答案 0 :(得分:11)

只要存在多种系统和交换数据的冲动,行分隔符和行终止符就是系统之间兼容性摩擦的来源。 Wikipedia article on the Newline对历史背景有一个很好的概述。并且,它提出了针对此问题的各种解决方案,专门用于Unix端或Windows端。

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

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

但请注意,该命令假定所有行都由CRLF(或LFCR)终止,并且只是从输入中删除每个CR字符。任何裸CR字符都将丢失。

在DOS和Windows方面,它过去常常很惨淡。 unix2dosdos2unix的端口肯定存在,例如它们包含在很多更大的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安装时,您可以为在“文本模式”下安装它的共享设置一个配置选项。以“文本模式”安装的共享会自动转换行结尾。如果它适合您,那可能是最干净的解决方案。两个系统都使用他们喜欢的文本文件格式,并且都不必大惊小怪。但仔细测试,这个解决方案充满了边缘案例和陷阱。最重要的是,不要指望文本模式文件系统挂载点上的二进制文件能够正确读取。他们经常会,但不一定总是。

答案 1 :(得分:7)

type inputfile | find /v "" > outputfile

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

答案 2 :(得分:1)

cat file | perl -pe 's/\R/\n/g'

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:1)

一种可能(虽然很麻烦)的方法是使用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=     ||#####################

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

  1. 每行末尾带有CR的文本文件。
  2. 文本文件,在行尾有一组重复的CR,后跟一行带有CRLF的空行。祝你好运!
  3. 在Notepad ++(免费应用程序)中打开文件并设置View - &gt;所有人物。

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

    1. 在Microsoft Wordpad中打开 - NOT - Word并以MSDOS格式保存文件。 ELSE IF以CR结尾,后跟以CRLF结尾的空白行
    2. 首先使用Notepad ++删除空白行。转到编辑 - &gt;线路操作 - &gt;删除空行并保存文件。
    3. 在Microsoft Wordpad中打开文件并以MSDOS格式保存。
    4. END IF