![](/img/trans.png)
[英]Can I replace Unix line endings with Windows line endings on the commandline?
[英]Windows command to convert Unix line endings?
是否有 Windows 命令來轉換文件的行尾?
我們有一個test.bat
,我們需要運行它來啟動我們的服務器。 我們使用 Perforce,並且我們需要在我們的工作區中有 unix 行尾。 出於某種原因,我們不允許在我們的工作區中將行尾更改為 Windows。 但是,服務器在 Windows 上運行。
每次我必須運行 bat 文件時,我都會在 Notepad++ 中打開它,然后選擇編輯→EOL 轉換→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) 連接起來將其寫入文件。
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 的有用答案。
這會在當前目錄下從LF改變所有.txt文件在地方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>(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
您可以創建一個簡單的批處理腳本來為您執行此操作:
TYPE %1 | MORE /P >%1.1
MOVE %1.1 %1
然后運行<batch script name> <FILE>
和<FILE>
將立即轉換為 DOS 行尾。
我在windows
上使用git bash
克隆了我的 git 項目。 然后所有文件都有LF
結尾。 我們的存儲庫默認以CRLF
結尾。
我刪除了該項目,然后使用Windows Command Prompt
再次克隆它。 那時CRLF
結尾完好無損。 就我而言,如果我改變了項目的結局,那么就會導致巨大的提交,並會給我的隊友帶來麻煩。 所以,就這樣做了。 希望這可以幫助某人。
如果您有 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 的 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
可能失敗的極端情況:-)
我只能說這個最后一個版本成功地恢復了我龐大的批處理庫中的行尾,所以例外,如果有的話,一定非常罕見!
根據 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
要將 UNIX(LF) 轉換為 Windows(CR-LF),請在 Windows 終端上使用下一個命令。
type file.txt > new_file.txt
遲到了,但仍然沒有使用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
在每一行findstr /n
加上<line number>:
,這樣可以避免跳過空行或以;
開頭的行;
.
要刪除<number>:
使用FOR "tokens=1,* delims=:"
選項,因為這也會刪除一行中的所有前導冒號。
因此行號被set "line=!line:*:=!"
刪除 ,這需要 EnableDelayedExpansion。
但是使用EnableDelayedExpansion
行set "line=%%L"
將刪除所有感嘆號和插入符號(僅當感嘆號在行中時)。
這就是為什么我之前禁用延遲擴展並且只在需要的兩行啟用它。
(echo(!line!)
看起來很奇怪,但有一個優點,即echo(
可以顯示!line!
任何內容!line!
並且外括號避免了行尾的意外空格。
我正在參加 AWS 課程並且經常不得不從 AWS Web 表單中的文本框復制到 Windows 記事本。 所以我只在剪貼板上得到了 LF 分隔的文本。 我偶然發現將它粘貼到我的 Delphi 編輯器中,然后按 Ctrl+K+W 會將文本寫入帶有 CR+LF 分隔符的文件中。 (我敢打賭許多其他 IDE 編輯器也會這樣做)。
遲到了,但我真的需要一個簡短、簡單、純粹的 Windows 解決方案。 很多其他答案,但我發現 FOR /F、MORE、FIND 等都以各種巧妙的方式失敗了,我不想使用 EXE、Python、VBS、Node 等。在現代,顯而易見的答案是為 PowerShell。 所以這是我的代碼。
ls <dir> | %{ (Get-Content $_.FullName) | Set-Content $_.FullName }
簡單吧? 與一個小附帶條件完美配合:如果沒有,它會在文件末尾添加一個 CRLF。 對我來說,這是一個獎勵,不是問題!
@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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.