有没有Windows命令可以转换文件的行结尾?
我们有一个需要运行来启动服务器的 test.bat
文件。 我们使用Perforce,并且我们需要在工作区中拥有Unix行结尾。由于某种原因,我们不被允许将行结尾更改为Windows。但是,服务器在Windows上运行。
每次我必须运行bat文件时,我都会在Notepad ++中打开它,然后选择Edit→EOL conversion→Windows。 有没有一种自动化这个过程的方法,以便我们不需要每次与Perforce同步时手动更改行结尾?
有没有Windows命令可以转换文件的行结尾?
我们有一个需要运行来启动服务器的 test.bat
文件。 我们使用Perforce,并且我们需要在工作区中拥有Unix行结尾。由于某种原因,我们不被允许将行结尾更改为Windows。但是,服务器在Windows上运行。
每次我必须运行bat文件时,我都会在Notepad ++中打开它,然后选择Edit→EOL conversion→Windows。 有没有一种自动化这个过程的方法,以便我们不需要每次与Perforce同步时手动更改行结尾?
使用Windows NT及更高版本中包含的more
命令可以轻松地完成此操作。要将包含UNIX EOL(行尾结束符)\n
的input_filename
转换为包含Windows EOL\r\n
的output_filename
,只需执行以下操作:
TYPE input_filename | MORE /P > output_filename
more
命令有一些额外的格式选项,你可能不知道。使用 more/?
命令来了解 more
的其他功能。
我曾处理过 CRLF
问题,因此决定创建一个非常简单的转换工具(在NodeJS中):
如果你已经安装了带npm的NodeJS,你可以试用它:
npm i -g eol-converter-cli
eolConverter crlf "**/*.{txt,js,java,etc}"
可以使用Glob正则表达式(与shell中相同的正则表达式)来动态配置路径。
因此,如果您可以使用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 换行符(CR-LF)连接后再将其写入文件。Get-Content
周围的括号使此操作成为可能)。至于一般的“原地”编辑:请参见此处。 - Ansgar WiechersWindows的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脚本,并根据您的平台将其添加到环境变量中:
@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 "delims=" %f in ('dir /b "*.txt"') do ( type "%f" | more /p > "%f.1" & move "%f.1" "%f" )
@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
试一下这个:
(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..
如果您拥有 Bash(例如 Git Bash),您可以使用以下脚本将 Unix 转换为 DOS:
ex filename.ext <<EOF
:set fileformat=dos
:wq
EOF
ex filename.ext <<EOF
:set fileformat=unix
:wq
EOF
以下是我的贡献,将文件夹中的多个文件进行转换:
for %%z in (*.txt) do (for /f "delims=" %%i in (%%z) do @echo %%i)>%%z.tmp
@echo off
setlocal DisableDelayedExpansion
for /f "tokens=1,* delims=:" %%k in ('findstr /n "^" %1') do echo.%%l
它通过以下方式避免了其他先前提出的 /f 批处理循环解决方案的缺陷:
1)延迟扩展关闭工作,以避免使用感叹号。
2)使用 for /f 分词器本身从 findstr /n
输出行中删除行号。
(使用 findstr /n 是必要的,以获取空白行:如果 for /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
tokens=*
将跳过初始行号。findstr /n
插入行号后作为标记分隔符。
我会让Jeb解释是否存在echo:something
可能失败的边界情况:-)
我只能说,这个最新版本成功地恢复了我巨大的batch library中的行尾,因此任何异常情况都应该非常罕见!
more /P <input_file >output_file
- Dimagog