Windows命令转换Unix行尾?


75

是否有Windows命令来转换文件的行尾?

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

每次必须运行bat文件时,都在Notepad ++中打开它,然后选择“编辑”→“终止转换”→“ Windows”。有没有一种自动化的方法,这样我们每次与Perforce同步时都不需要手动更改行尾?

提前致谢。

Answers:


63

使用moreWindows NT和更高版本中包含的命令,实际上可以非常轻松地完成此操作。转换input_filename包含UNIX EOL(行尾)\noutput_filename其中包含的Windows EOL \r\n,只是这样做:

TYPE input_filename | MORE /P > output_filename

more命令还有您可能不知道的其他格式设置选项。奔跑more/?学习其他more可以做什么。


2
这似乎为不以换行符结尾的文件添加了一个新的换行符,如果这对于您的特定情况很重要,则只是提示。
aolszowka '16

2
我需要与此相反。任何想法?
罗斯·布里格里

2
好答案!稍微简单一点:more /P <input_file >output_file
Dimagog

5
@Sebastian什么是Windows 9?
MD XF

1
@adrianTNT,您做到了TYPE input_file | MORE /P > input_file
安德鲁·

30

使用unix2dos实用程序。您可以在此处下载二进制文件。


1
同样,它只是notepad ++的替代品。不会真正实现自动化。我将必须运行此工具。到目前为止,我确实在notepad ++中更改了行尾。
Deepti Jain

11
这是一个命令行工具。而且它更适合于自动化,然后是GUI工具。您可以编写一个定期at作业,该作业会过滤放入批处理文件的某个文件夹中的所有文件。这完全取决于自动化的含义。
David Jashi

17

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

这是NodeJS EOL转换器CLI

因此,如果您安装了带有npm的NodeJS,则可以尝试:

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

可以使用Glob regex(与shell中相同的regex)动态配置路径。

因此,如果可以使用NodeJS,它非常简单,可以集成此命令将整个工作区转换为所需的行尾。



15

您可以在不使用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之前将其与Windows换行符(CR-LF)连接在一起。


2
@FranklinYu使用PowerShell方法,您可以将修改后的内容写回到同一文件(括号内Get-Content可以实现)。至于一般的“就地”编辑:请参见此处
Ansgar Wiechers,

对于带有-replace的第一个powershell方法,您必须将-raw选项添加到get-content来完成您想要的操作。只是不要在同一文件上执行两次。您甚至都不需要引用文件名。请注意,在Powershell 5中使用“>”或“ out-file”会生成一个“ unicode”编码的文件,而不是“ ansi”。
js2010年

11

Windows的MORE并不可靠,它不可避免地破坏了TAB并增加了线条。

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

python出现时,此一线将任何行尾转换为当前平台-在任何平台上:

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

8

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

这将改变所有.txt文件来代替当前目录从LF到CRLF在命令提示符

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

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

移动

/ y

包括子目录更改

目录/ b

目录/ b / s

在批处理文件(包括子目录)中完成所有这些操作,而无需在下面提示使用

@echo off
setlocal enabledelayedexpansion

for /f %%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

5

尝试这个:

(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>(对于/ 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 39 31 39 32..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 ..

1
它可以工作,但似乎也可以从文件中删除所有空白行。:(
MarioVilas 2014年

2
@MarioVilas是的,你是对的。您可以为此使用翻页
Endoro 2014年

3

为此,我对文件夹中的多个文件进行了转换: for %%z in (*.txt) do (for /f "delims=" %%i in (%%z) do @echo %%i)>%%z.tmp


2

您可以创建一个简单的批处理脚本来为您执行此操作:

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

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


2

我使用git bashon克隆了我的git项目windows。然后所有文件都有LF结尾。我们的存储库CRLF默认具有结尾。

我删除了该项目,然后使用再次克隆了该项目Windows Command Prompt。该CRLF结局完好即可。就我而言,如果我改变了项目的结局,那将导致巨大的投入,并给我的队友带来麻烦。所以,是这样做的。希望这对某人有帮助。


有一种使用git将CRLF转换为LF的方法,我只是使用您的方法来获得LF结尾,但我无法使其正常工作。所以我决定更改git config,这里是一个代码段:$ git config --global core.autocrlf输入
Ziumper

1

根据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

Ir Relevant的解决方案除删除所有感叹号(!)之外均能正常工作。
mgcoder 2015年

1

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

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

同样,要从dos2unix进行转换:

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

1

晚会晚了,但是仍然没有使用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:*:=!",这需要EnableDelayedExpansion。
但是使用EnableDelayedExpansion该行set "line=%%L"会丢弃所有感叹号和插入号(仅当感叹号在行中时)。

这就是为什么我之前禁用延迟扩展,而仅在需要的两行启用延迟扩展的原因。

(echo(!line!)看起来很奇怪,但有个好处,即echo(可以显示任何内容!line!和外括号避免在线路末端accidentials空格。


1

这是一个简单的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来获得空白行:如果直接从输入文件中读取/ f,则会将其删除。)

但是,正如Jeb在下面的评论中指出的那样,上述解决方案有一个缺点,而其他缺点则没有:在行首删除冒号。

所以2020-04-06更新只是为了好玩,这是另一个基于findstr.exe的1-liner,似乎在没有上述缺点的情况下可以正常工作:

@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可能失败的特殊情况:-)
我只能说最后一个版本成功恢复了我庞大的批处理库中的行尾,因此,异常(如果有的话)一定很少见!


这会:从行首删除所有冒号。那会破坏所有批处理功能。顺便说一句。测试以将文件转换为类似的行\..\..\windows\system32\calc.exe。为了解决这个问题,请看下面的解释
jeb

你是对的!我想做一个比以前发布的解决方案更简单,更好的1-liner,但是显然这不能完成。您的是迄今为止唯一正确的。
让弗朗索瓦Larvoire

但是挑战是不可抗拒的,也许我现在已经找到了另一种1行解决方案,如上面的编辑文本所示:-)
让·弗朗索瓦·Larvoire

然后您又失败了:-)试试看..\..\..\..\..\windows\system32\calc.exe。唯一安全的ECHO表单是echo(。一个班轮是可能的,但我认为这很棘手
jeb

卡兰巴,舍恩·维德·韦尔帕斯!好,我暂时放弃。但是我敢肯定,有一天,我会成功的!:-)
让·弗朗索瓦·Larvoire

0

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


0

要将UNIX(LF)转换为Windows(CR-LF),请使用next命令

type file.txt > new_file.txt

-2

将回车符插入文本文件

@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

2
实际上,如果他仅使用,就可以工作(for /f "tokens=*" %%a in (%~1) do @echo.%%a)>"%~2"
Ansgar Wiechers 2013年

@AnsgarWiechers是的,这set TargetFile=%2 rem c:\test\out.txt也需要改进。而且,顺便说一句,你"tokens=*"也是。
Endoro

1
@Endoro REM是批处理文件中的注释,您可以取出%1 rem,然后为其提供所需的特定文件。当我提供链接时,因为您已经在使用批处理文件,所以我觉得我不需要进一步的文档了,对吗?请对其进行测试,因为它可以正常工作,并且可以随意将其集成到您现有的批处理文件中。谢谢!
吉米·史密斯

在Windows 7中对我来说运行良好。我在Notepad ++中使用Unix的EOL创建了文件c:\ test \ test.txt。之后,我只运行了批处理文件。再说一遍,这不是我的代码,而是我稍加修改以不显示记事本的代码?我可以向OP展示如何使其与最后一条评论相反。
吉米·史密斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.