有没有办法将所有CR转换为文本文件中的CRLF?
当我在Windows上从Linux服务器打开文本文件时,所有文本都显示在一行中,但实际上它是多行文本。
我想在批处理文件中执行转换。
有人可以提出建议吗?
答案 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方面,它过去常常很惨淡。 unix2dos
和dos2unix
的端口肯定存在,例如它们包含在很多更大的Cygwin工具中,这些工具在Windows机器上提供完整的unix仿真。但是很难找到仅使用内置功能的解决方案。
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)
一种荒谬的方式。适用于以下场景:
在Notepad ++(免费应用程序)中打开文件并设置View - &gt;所有人物。
如果所有行以CR结尾,则:
END IF