簡體   English   中英

Windows 命令轉換 Unix 行尾?

[英]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功能。

使用unix2dos實用程序。 您可以在此處下載二進制文件。

我正在處理CRLF問題,所以我決定構建非常簡單的轉換工具(在 NodeJS 中):

它是NodeJS EOL 轉換器 CLI

因此,如果您安裝了帶有 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。
但是使用EnableDelayedExpansionset "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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM