是否有Windows命令来转换文件的行尾?
我们test.bat
需要运行一个启动服务器。我们使用Perforce,我们需要在工作区中使用unix行尾。由于某些原因,我们不允许在工作区中将行尾更改为Windows。但是,服务器在Windows上运行。
每次必须运行bat文件时,都在Notepad ++中打开它,然后选择“编辑”→“终止转换”→“ Windows”。有没有一种自动化的方法,这样我们每次与Perforce同步时都不需要手动更改行尾?
提前致谢。
是否有Windows命令来转换文件的行尾?
我们test.bat
需要运行一个启动服务器。我们使用Perforce,我们需要在工作区中使用unix行尾。由于某些原因,我们不允许在工作区中将行尾更改为Windows。但是,服务器在Windows上运行。
每次必须运行bat文件时,都在Notepad ++中打开它,然后选择“编辑”→“终止转换”→“ Windows”。有没有一种自动化的方法,这样我们每次与Perforce同步时都不需要手动更改行尾?
提前致谢。
Answers:
使用more
Windows NT和更高版本中包含的命令,实际上可以非常轻松地完成此操作。转换input_filename
包含UNIX EOL(行尾)\n
到output_filename
其中包含的Windows EOL \r\n
,只是这样做:
TYPE input_filename | MORE /P > output_filename
该more
命令还有您可能不知道的其他格式设置选项。奔跑more/?
学习其他more
可以做什么。
more /P <input_file >output_file
TYPE input_file | MORE /P > input_file
at
作业,该作业会过滤放入批处理文件的某个文件夹中的所有文件。这完全取决于自动化的含义。
我当时正在处理CRLF
问题,所以我决定构建一个非常简单的转换工具(在NodeJS中):
因此,如果您安装了带有npm的NodeJS,则可以尝试:
npm i -g eol-converter-cli
eolConverter crlf "**/*.{txt,js,java,etc}"
可以使用Glob regex(与shell中相同的regex)动态配置路径。
因此,如果可以使用NodeJS,它非常简单,可以集成此命令将整个工作区转换为所需的行尾。
您可以在不使用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)连接在一起。
Get-Content
可以实现)。至于一般的“就地”编辑:请参见此处。
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
基于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
尝试这个:
(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 ..
我使用git bash
on克隆了我的git项目windows
。然后所有文件都有LF
结尾。我们的存储库CRLF
默认具有结尾。
我删除了该项目,然后使用再次克隆了该项目Windows Command Prompt
。该CRLF
结局完好即可。就我而言,如果我改变了项目的结局,那将导致巨大的投入,并给我的队友带来麻烦。所以,是这样做的。希望这对某人有帮助。
根据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
晚会晚了,但是仍然没有使用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空格。
这是一个简单的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
。唯一安全的ECHO表单是echo(
。一个班轮是可能的,但我认为这很棘手
@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
(for /f "tokens=*" %%a in (%~1) do @echo.%%a)>"%~2"
。
set TargetFile=%2 rem c:\test\out.txt
也需要改进。而且,顺便说一句,你"tokens=*"
也是。