Windows命令转换Unix行结尾?

时间:2013-07-10 19:42:52

标签: windows unix batch-file cmd eol

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

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

每次我必须运行bat文件时,我在Notepad ++中打开它并选择编辑→EOL转换→Windows。有没有办法实现自动化,这样我们每次与Perforce同步时都不需要手动更改行结尾?

提前致谢。

17 个答案:

答案 0 :(得分:55)

使用Windows NT及更高版本中包含的more命令实际上可以非常轻松地完成此操作。要将包含UNIX EOL(行尾)input_filename的{​​{1}}转换为包含Windows EOL \n的{​​{1}},请执行以下操作:

output_filename

\r\n命令具有您可能不知道的其他格式选项。运行TYPE input_filename | MORE /P > output_filename 以了解其他more可以执行的操作。

答案 1 :(得分:26)

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

答案 2 :(得分: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连接在将其写入文件之前的换行符(CR-LF)。

答案 3 :(得分:10)

视窗&#39;更多是不可靠的,它不可避免地摧毁了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

答案 4 :(得分:9)

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

这是NodeJS EOL converter CLI

因此,如果您安装了 NodeJS并且安装了 ,您可以尝试一下:

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

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

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

答案 5 :(得分:6)

以TampaHaze&MD和FF的有用答案为基础。

这会将当前目录中的所有.txt文件到位从命令提示符中的LF更改为CRLF

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

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

  

移动

  

move / y

要包含子目录更改

  

dir / b

  

dir / 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

答案 6 :(得分: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>(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..

答案 7 :(得分:3)

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

答案 8 :(得分:1)

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

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

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

答案 9 :(得分:1)

该聚会迟到了,但是使用FOR /F循环仍然没有正确答案。
(但是您根本不需要FOR循环,solution from @TampaHaze也可以工作,并且更简单)

answer from @IR relevant有一些缺点。
它会删除感叹号,也可能会删除插入符号。

@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。
但是使用EnableDelayedExpansionset "line=%%L"会删除所有感叹号和脱字符(仅当感叹号在行中时)。

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

(echo(!line!)看起来很奇怪,但是具有优势,echo(可以显示!line!中的任何内容,并且外部括号可以避免行尾出现意外空格。

答案 10 :(得分: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可能会失败:-)
我只能说这最后一个版本成功恢复了我巨大的batch library上的行结尾,因此,异常(如果有的话)一定很少见!

答案 11 :(得分: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

答案 12 :(得分:0)

我在int state = 0, count = 0; TextView textView; CountDownTimer timer; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); button=(Button)findViewById(R.id.b_main); textView =(TextView) findViewById(R.id.text_main); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (state == 0) { state = 1; startTimer(); } else { state = 0; if (timer != null) { timer.cancel(); } textView.setText("Stop " + count++); } } }); } public void startTimer() { timer = new CountDownTimer(10000, 1000) { @Override public void onTick(long millisUntilFinished) { count++; textView.setText("Start " + count); } @Override public void onFinish() { //10 sec finished } }; timer.start(); } 上使用git bash克隆了我的git项目。这样,所有文件都以windows结尾。我们的存储库默认以LF结尾。

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

答案 13 :(得分:0)

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

答案 14 :(得分:0)

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

type file.txt > new_file.txt

答案 15 :(得分:0)

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

d1.rename(columns={'ProductType':'Product'}).set_index('Product').combine_first(d2.set_index('Product')).reset_index()

类似地,要从dos2unix进行转换:

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

答案 16 :(得分:-2)

Inserting Carriage Returns to a Text File

@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