Windows 命令转换 Unix 行结束符吗?

是否有 Windows 命令来转换文件的行结束符?

我们有一个 test.bat,我们需要运行启动我们的服务器。我们使用 Perforce,并且需要在工作区中使用 unix 行结尾。由于某些原因,我们不允许在工作区中将行结束符更改为 Windows。但是,服务器在 Windows 上运行。

每次我必须运行 bat 文件,我打开它在记事本 + + 和选择编辑 & rarr; EOL 转换 & rarr; Windows。有没有一种自动化的方法,这样我们就不需要手动更改行结束每次我们同步与 Perforce?

先谢谢你。

148397 次浏览

使用 Unix2dos实用程序。您可以下载二进制文件 给你

向文本文件插入回车符

@echo off
set SourceFile=%1 rem c:\test\test.txt
set TargetFile=%2 rem c:\test\out.txt


if exist "%TargetFile%" del "%TargetFile%"
for /F "delims=" %%a in ('type "%SourceFile%"') do call :Sub %%a
rem notepad "%TargetFile%"
goto :eof




:Sub
echo %1 >> "%TargetFile%"
if "%2"=="" goto :eof
shift
goto sub

您可以在 VBScript 中不使用其他工具来完成这项工作:

Do Until WScript.StdIn.AtEndOfStream
WScript.StdOut.WriteLine WScript.StdIn.ReadLine
Loop

将上面的代码行放在一个 unix2dos.vbs文件中,然后像下面这样运行:

cscript //NoLogo unix2dos.vbs <C:\path\to\input.txt >C:\path\to\output.txt

或者像这样:

type C:\path\to\input.txt | cscript //NoLogo unix2dos.vbs >C:\path\to\output.txt

你也可以在 PowerShell 中这样做:

(Get-Content "C:\path\to\input.txt") -replace "`n", "`r`n" |
Set-Content "C:\path\to\output.txt"

可进一步简化为:

(Get-Content "C:\path\to\input.txt") | Set-Content "C:\path\to\output.txt"

上面的语句在没有显式替换的情况下工作,因为 Get-Content在任何类型的换行符(CR、 LF 和 CR-LF)下隐式地分割输入文件,而 Set-Content在将输入数组写入文件之前将输入数组与 Windows 换行符(CR-LF)连接起来。

试试这个:

(for /f "delims=" %i in (file.unix) do @echo %i)>file.dos

会议协议:

C:\TEST>xxd -g1 file.unix
0000000: 36 31 36 38 39 36 32 39 33 30 38 31 30 38 36 35  6168962930810865
0000010: 0a 34 38 36 38 39 37 34 36 33 32 36 31 38 31 39  .486897463261819
0000020: 37 0a 37 32 30 30 31 33 37 33 39 31 39 32 38 35  7.72001373919285
0000030: 34 37 0a 35 30 32 32 38 31 35 37 33 32 30 32 30  47.5022815732020
0000040: 35 32 34 0a                                      524.


C:\TEST>(for /f "delims=" %i in (file.unix) do @echo %i)>file.dos


C:\TEST>xxd -g1 file.dos
0000000: 36 31 36 38 39 36 32 39 33 30 38 31 30 38 36 35  6168962930810865
0000010: 0d 0a 34 38 36 38 39 37 34 36 33 32 36 31 38 31  ..48689746326181
0000020: 39 37 0d 0a 37 32 30 30 31 33 37 33 39 31 39 32  97..720013739192
0000030: 38 35 34 37 0d 0a 35 30 32 32 38 31 35 37 33 32  8547..5022815732
0000040: 30 32 30 35 32 34 0d 0a                          020524..

我对此的贡献是在一个文件夹中转换多个文件: for %%z in (*.txt) do (for /f "delims=" %%i in (%%z) do @echo %%i)>%%z.tmp

基于 Endoro 的回答,但为了保持空白,试试这个:

@echo off
setlocal enabledelayedexpansion
(for /f "tokens=* delims=:" %%i in ('findstr /n "^" file.unix') do (
set line=%%i
set line=!line:*:=!
echo(!line!
))>file.dos

实际上,使用包含在 WindowsNT 和更高版本中的 more命令可以非常容易地完成这项工作。要将包含 UNIX EOL (行尾) \ninput_filename转换为包含 Windows EOL \r\noutput_filename,只需执行以下操作:

TYPE input_filename | MORE /P > output_filename

more命令具有您可能不知道的其他格式设置选项。运行 more/?以了解 more还能做什么。

Windows 的 MORE 是不可靠的,它不可避免地破坏标签,并添加行。

Unix2dos 也是 MinGW/MSYS、 Cygutils、 GnuWin32和其他 unix 二进制端口集合的一部分——可能已经安装了。

巨蟒存在时,这个一行程序将任何线端转换为当前平台——在任何平台上:

TYPE UNIXFILE.EXT | python -c "import sys; sys.stdout.write(sys.stdin.read())" > MYPLATFILE.EXT

或者

python -c "import sys; sys.stdout.write(open(sys.argv[1]).read())" UNIXFILE.EXT > MYPLATFILE.EXT

或者将一行程序放入. bat/shell 脚本中,并根据您的平台放在 PATH 上:

@REM This is any2here.bat
python -c "import sys; sys.stdout.write(open(sys.argv[1]).read())" %1

用这个工具就像

any2here UNIXFILE.EXT > MYPLATFILE.EXT

您可以创建一个简单的批处理脚本来完成以下任务:

TYPE %1 | MORE /P >%1.1
MOVE %1.1 %1

然后运行 <batch script name> <FILE><FILE>将立即转换为 DOS 行结束。

我正在处理 CRLF的问题,所以我决定构建一个非常简单的转换工具(在 NodeJS 中) :

EOL 转换器

所以如果你已经安装了 带 npm 的 NodeJS,你可以试试:

npm i -g eol-converter-cli
eolConverter crlf "**/*.{txt,js,java,etc}"

路径可以通过使用 Glob 正则表达式动态配置(与 shell 中的正则表达式相同)。

因此,如果您可以使用 NodeJS,那么它非常简单,并且您可以集成这个命令来将整个工作区转换为所需的行结束符。

基于 TampaHaze 和 MD XF 的有用答案。

这将把工作目录中的所有. txt 文件从命令提示符中的 LF 改为 CRLF

for /f "delims=" %f in ('dir /b "*.txt"') do ( type "%f" | more /p > "%f.1" & move "%f.1" "%f" )

如果您不想验证每一个更改

让开

快走

包含子目录更改

目录

导演/导演/导演

要在一个包括子目录的批处理文件中完成所有这些操作,而不提示 .txt文件,请使用下面的命令

@echo off
setlocal enabledelayedexpansion


for /f "delims=" %%f in ('dir /s /b "*.txt"') do (
type "%%f" | more /p > "%%f.1"
move /y "%%f.1" "%%f" > nul
@echo Changing LF-^>CRLF in File %%f
)
echo.
pause

我使用 windows上的 git bash克隆了我的 git 项目。所有的文件都以 LF结尾。我们的存储库默认使用 CRLF结尾。

我删除了该项目,然后使用 Windows Command Prompt再次克隆了它。当时 CRLF末端是完整的。在我的例子中,如果我改变了项目的结局,那么这将导致一个巨大的提交,并且会给我的队友带来麻烦。所以,就这样做了。希望这对谁有帮助。

我正在学习 AWS 课程,并且经常不得不从 AWS web 表单中的文本框复制到 Windows 记事本。所以我只能在剪贴板上看到 LF 分隔的文本。我偶然发现,粘贴到我的 Delphi 编辑器,然后点击 Ctrl + K + W 将写文本到一个文件与 CR + LF 分隔符。(我敢打赌,许多其他 IDE 编辑器也会这样做)。

要将 UNIX (LF)转换为 Windows (CR-LF) ,请在 Windows 终端上使用下一个命令。

type file.txt > new_file.txt

如果使用 bash (例如 git bash) ,可以使用以下脚本从 unix2dos 进行转换:

ex filename.ext <<EOF
:set fileformat=dos
:wq
EOF

类似地,从 dos2unix 转换:

ex filename.ext <<EOF
:set fileformat=unix
:wq
EOF

下面是一个简单的 unix2dos.bat 文件,它保留了空行和感叹号:

@echo off
setlocal DisableDelayedExpansion
for /f "tokens=1,* delims=:" %%k in ('findstr /n "^" %1') do echo.%%l

输出转到标准输出,因此如果需要,可以将 unix2dos.bat 输出重定向到一个文件。

它通过以下方式避免了以前提出的/f 批量循环解决方案的缺陷:
1)工作时延展关闭,避免吃掉感叹号。
2)使用 for/f 标记符本身从 findstr /n输出行中删除行号。
(还需要使用 findstr/n 来获得空行: 如果 for/f 直接从输入文件读取,那么它们将被删除。)

但是,正如 Jeb 在下面的注释中指出的那样,上述解决方案有一个其他解决方案没有的缺点: 它在行首省略了冒号。

因此,2020-04-06更新只是为了好玩,这里有另一个基于 findstr.exe 的一行程序,它似乎工作得很好,没有上述缺点:

@echo off
setlocal DisableDelayedExpansion
for /f "tokens=* delims=0123456789" %%l in ('findstr /n "^" %1') do echo%%l

附加技巧如下:
3)使用数字0-9作为分隔符,这样 tokens=*就会跳过初始行号。
4)使用由 findstr /n在行号后插入的冒号作为 echo 命令后面的标记分隔符。

我将留给 Jeb 来解释 echo:something是否有可能失败的边缘案例: -)
我所能说的是,这最后一个版本成功地恢复行结束在我的巨大的 批处理程序库批处理程序库,所以例外,如果有的话,必须是相当罕见的!

派对迟到了,但还有 使用 FOR /F循环没有正确答案。
(但是您根本不需要 FOR 循环,来自@TampaHaze 的解决方案也可以工作,而且要简单得多)

来自@IR 的回答有一些缺点。
它删除了感叹号,也可以删除插入符号。

@echo off
(
setlocal Disabledelayedexpansion
for /f "tokens=* delims=" %%L in ('findstr /n "^" "%~1"') do (
set "line=%%L"
setlocal enabledelayedexpansion
set "line=!line:*:=!"
(echo(!line!)
endlocal
)
) > file.dos

诀窍是使用 findstr /n为每行加上 <line number>:的前缀,这样可以避免跳过以 ;开头的空行或行。
要删除 <number>:,不能使用 FOR "tokens=1,* delims=:"选项,因为这也会删除一行中的所有前导冒号。

因此,行号被 set "line=!line:*:=!"删除,这需要 EnableDelayed 。
但使用 EnableDelayedExpansion时,行 set "line=%%L"将删除所有感叹号和插入符号(仅当感叹号在行中时)。

这就是为什么我之前禁用了延迟扩展,并且只在需要它的两条线路上启用它。

(echo(!line!)看起来很奇怪,但是它有一个优点,那就是 echo(可以显示 !line!中的任何内容,而且外括号可以避免行尾处的意外空白。

派对迟到了,但我真的需要一个简短,简单,纯粹的 Windows 解决方案。还有很多其他的答案,但是我发现 FOR/F、 MORE、 FIND 等都以各种巧妙的方式失败了,我不想使用 EXE、 Python、 VBS、 Node 等等。在当今这个时代,显而易见的答案就是 PowerShell。这是我的代码。

ls <dir> | %{ (Get-Content $_.FullName) | Set-Content $_.FullName }

很简单吧?只要有一个小小的附加条件就可以完美地工作: 如果文件末尾没有 CRLF,它就会添加一个 CRLF。对我来说,那是额外的奖励,不是问题!