Windows command to convert Unix line endings?
Asked Answered
I

19

87

Is there a Windows command to convert line endings of a file?

We have a test.bat which we need to run to start our server. We use Perforce and we need to have unix line endings in our workspace. For some reason, we are not allowed to change line endings to Windows in our workspaces. However, the server runs on Windows.

Everytime I have to run the bat file, I open it in Notepad++ and choose Edit→EOL conversion→Windows. Is there a way to automate this so that we won't need to manually change the line endings everytime we sync with Perforce?

Internuncio answered 10/7, 2013 at 19:42 Comment(0)
M
73

This can actually be done very easily using the more command which is included in Windows NT and later. To convert input_filename which contains UNIX EOL (End Of Line) \n to output_filename which contains Windows EOL \r\n, just do this:

TYPE input_filename | MORE /P > output_filename

The more command has additional formatting options that you may not be aware of. Run more/? to learn what else more can do.

Manassas answered 8/1, 2015 at 16:8 Comment(9)
this still works great in Windows 9, thanks! Might be worth mentioning that the file output_filename has to be existing before running this command and its content will be overwritten.Broddie
This seems to add an additional Newline to files that do not end with a newline, just a heads up if this matters for your particular scenario.Junkojunkyard
Unfortunately this also botches all the tabs to spaces.Aboulia
I need the opposite of this. any idea?Hill
Great answer! Slightly simpler: more /P <input_file >output_fileNedra
@Sebastian What's Windows 9?Fakery
@adrianTNT, you did TYPE input_file | MORE /P > input_fileArchducal
@AndrewSteitz He wanted an in-place conversion.Gyrocompass
@FranklinYu, you are correct. I was perplexed by your comment at first and then I realized that in my previous comment I forgot the "?" because I was asking (very poorly) if he actually typed that on the command line. Doh! I was asking (well, meant to ask) him because I was sure that it worked and even tried it to be 100% certain. Punctuation matters (and I goofed). I like the example "Can we eat, Grandma?" vs "Can we eat Grandma?" (1st, ask Grandma if we can eat. 2nd, asking someone else if we can eat Grandma, LOL). Thank you for pointing out my mistake so I could clarify!!!Archducal
T
35

Use unix2dos utility. You can download binaries here.

Trautman answered 10/7, 2013 at 19:48 Comment(2)
Again its just an alternative to notepad++. Won't really get this automated. I will have to run this tool. I do change the line endings in notepad++ as of now.Internuncio
It's a command line tool. And it's more suitable for automation, then GUI tools. You may write a periodical at job, which filters all files in some folder you put your batch files in. It all depends on what do you mean by automation.Trautman
B
21

I was dealing with CRLF issues so I decided to build really simple tool for conversion (in NodeJS):

It's NodeJS EOL converter CLI

So if you have NodeJS with npm installed you can try it:

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

Path might be configured dynamically by using Glob regex (same regex as in shell).

So if you can use NodeJS, it's really simple and you can integrate this command to convert whole workspace to desired line endings.

Backset answered 28/6, 2017 at 14:45 Comment(1)
Looks like your solution hit reddit.com/r/programmingcirclejerk/comments/6t3kel/…Instauration
A
16

You can do this without additional tools in VBScript:

Do Until WScript.StdIn.AtEndOfStream
  WScript.StdOut.WriteLine WScript.StdIn.ReadLine
Loop

Put the above lines in a file unix2dos.vbs and run it like this:

cscript //NoLogo unix2dos.vbs <C:\path\to\input.txt >C:\path\to\output.txt

or like this:

type C:\path\to\input.txt | cscript //NoLogo unix2dos.vbs >C:\path\to\output.txt

You can also do it in PowerShell:

(Get-Content "C:\path\to\input.txt") -replace "`n", "`r`n" |
  Set-Content "C:\path\to\output.txt"

which could be further simplified to this:

(Get-Content "C:\path\to\input.txt") | Set-Content "C:\path\to\output.txt"

The above statement works without an explicit replacement, because Get-Content implicitly splits input files at any kind of linebreak (CR, LF, and CR-LF), and Set-Content joins the input array with Windows linebreaks (CR-LF) before writing it to a file.

Antiworld answered 10/7, 2013 at 20:42 Comment(2)
@FranklinYu With the PowerShell approach you can write the modified content back to the same file (the parentheses around Get-Content make that possible). As for "in-place" editing in general: see here.Antiworld
For that first powershell method with -replace, you would have to add the -raw option to get-content to do what you intend. Just don't do it twice on the same file. You don't even need to quote the filenames. Note that using ">" or "out-file" in powershell 5 results in a "unicode" encoded file vs "ansi".Wallis
L
13

Windows' MORE is not reliable, it destroys TABs inevitably and adds lines.

unix2dos is part also of MinGW/MSYS, Cygutils, GnuWin32 and other unix binary port collections - and may already be installed.

When python is there, this one-liner converts any line endings to current platform - on any platform:

TYPE UNIXFILE.EXT | python -c "import sys; sys.stdout.write(sys.stdin.read())" > MYPLATFILE.EXT

or

python -c "import sys; sys.stdout.write(open(sys.argv[1]).read())" UNIXFILE.EXT > MYPLATFILE.EXT

Or put the one-liner into a .bat / shell script and on the PATH according to your platform:

@REM This is any2here.bat
python -c "import sys; sys.stdout.write(open(sys.argv[1]).read())" %1

and use that tool like

any2here UNIXFILE.EXT > MYPLATFILE.EXT
Lightsome answered 26/2, 2016 at 21:11 Comment(0)
C
8

Building on TampaHaze's and MD XF's helpful answers.

This will change all .txt files in place in the current directory from from LF to CRLF in Command Prompt

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

If you don't want to verify every single change

move

To

move /y

To include subdirectories change

dir /b

To

dir /b /s

To do all this in a batch file including subdirectories without prompting for .txt files use below

@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
Chiou answered 3/5, 2018 at 12:32 Comment(1)
Nope, this fails completely if there is a space in the filepath, such as, say, "C:\Program Files\FileMaker\FileMaker Server\HTTPServer\conf\".Lemley
V
6

try this:

(for /f "delims=" %i in (file.unix) do @echo %i)>file.dos

Session protocol:

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..
Varistor answered 10/7, 2013 at 21:11 Comment(2)
It works, but it also seems to remove all blank lines from the file. :(Termination
@Termination yes, you are right. You can use flip for this.Varistor
J
3

My contribution for this, converting several files in a folder: for %%z in (*.txt) do (for /f "delims=" %%i in (%%z) do @echo %%i)>%%z.tmp

Jaw answered 7/11, 2013 at 22:22 Comment(0)
T
3

If you have bash (e.g. git bash), you can use the following script to convert from unix2dos:

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

similarly, to convert from dos2unix:

ex filename.ext <<EOF
:set fileformat=unix
:wq
EOF
Tripping answered 3/10, 2019 at 21:48 Comment(0)
F
2

You could create a simple batch script to do this for you:

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

Then run <batch script name> <FILE> and <FILE> will be instantly converted to DOS line endings.

Fakery answered 10/5, 2017 at 17:20 Comment(0)
U
2

I cloned my git project using the git bash on windows. All the files then had LF endings. Our repository has CRLF endings as default.

I deleted the project, and then cloned it again using the Windows Command Prompt. The CRLF endings were intact then. In my case, if I had changed the endings for the project, then it would've resulted in a huge commit and would've caused trouble for my teammates. So, did it this way. Hope this helps somebody.

Ulyssesumayyad answered 22/8, 2018 at 11:1 Comment(1)
There is a way to use git to convert CRLF to LF i just used your approach to get LF ending, but i can not get it working. so i decided to change git configs here is a snippet: $ git config --global core.autocrlf inputWagonette
D
2

Here's a simple unix2dos.bat file that preserves blank lines and exclamation points:

@echo off
setlocal DisableDelayedExpansion
for /f "tokens=1,* delims=:" %%k in ('findstr /n "^" %1') do echo.%%l

The output goes to standard out, so redirect unix2dos.bat output to a file if so desired.

It avoids the pitfalls of other previously proposed for /f batch loop solutions by:
1) Working with delayed expansion off, to avoid eating up exclamation marks.
2) Using the for /f tokenizer itself to remove the line number from the findstr /n output lines.
(Using findstr /n is necessary to also get blank lines: They would be dropped if for /f read directly from the input file.)

But, as Jeb pointed out in a comment below, the above solution has one drawback the others don't: It drops colons at the beginning of lines.

So 2020-04-06 update just for fun, here's another 1-liner based on findstr.exe, that seems to work fine without the above drawbacks:

@echo off
setlocal DisableDelayedExpansion
for /f "tokens=* delims=0123456789" %%l in ('findstr /n "^" %1') do echo%%l

The additional tricks are:
3) Use digits 0-9 as delimiters, so that tokens=* skips the initial line number.
4) Use the colon, inserted by findstr /n after the line number, as the token separator after the echo command.

I'll leave it to Jeb to explain if there are corner cases where echo:something might fail :-)
All I can say is that this last version successfully restored line endings on my huge batch library, so exceptions, if any, must be quite rare!

Downwards answered 23/1, 2020 at 10:42 Comment(8)
This drops all colons : from line beginnings. That destroys all batch functions. Btw. Test to convert a file with a line like \..\..\windows\system32\calc.exe. To solve this look at this explanationYounker
You're right! I wanted to do a 1-liner, simpler and better than the previously published solutions, but apparently this cannot be done. Yours is the only correct so far.Salad
But the challenge was irresistible, and maybe I have found another 1-line solution now, as shown in the edited text above :-)Salad
And you failed again :-) Try it with ..\..\..\..\..\windows\system32\calc.exe. The only safe ECHO form is the echo(. A one liner could be possible, but I suppose it's trickyYounker
Caramba, schon wieder verpaßt! OK, I give up for now. But I'm sure that one day, I'll make it! :-)Salad
Jeez, how many "ifs, ands, or buts" does Windows make things require? I can't follow any of this. I never thought the single most time consuming part of developing a whole custom PHP database view would be dealing with the line endings after copying the finished project to our server. Is there no Windows utility than can just fix this extremely common problem without all this headscratching?Lemley
UPDATE: Did it with Notepad++.Lemley
@John Smith: There are lots of ports of the unix2dos and dos2unix programs for Windows, which easily resolve the initial problem. See kxr's answer below https://mcmap.net/q/169586/-windows-command-to-convert-unix-line-endings for details. Here, purely for the sake of the art, I was trying to do it using a short Windows batch script. This is very hard to do in that poor scripting language, if possible at all. But this very difficulty is why some of us find it a fun challenge. :-)Salad
O
1

Based on Endoro's answer but to keep the blanks, try this:

@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
Overcharge answered 8/8, 2014 at 15:2 Comment(1)
Ir Relevant's solution works fine except it drop all exclamation mark (!).Wind
H
1

For convert UNIX(LF) to Windows(CR-LF) use next command on your windows terminal.

type file.txt > new_file.txt
Hipster answered 4/9, 2019 at 13:42 Comment(0)
Y
1

Late to the party, but there is still no correct answer using a FOR /F loop.
(But you don't need a FOR loop at all, the solution from @TampaHaze works too and is much simpler)

The answer from @IR relevant has some drawbacks.
It drops the exclamation marks and can also drop carets.

@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

The trick is to use findstr /n to prefix each line with <line number>:, this avoids skipping of empty lines or lines beginning with ;.
To remove the <number>: the FOR "tokens=1,* delims=:" option can't be used, because this would remove all leading colons in a line, too.

Therefore the line number is removed by set "line=!line:*:=!", this requires EnableDelayedExpansion.
But with EnableDelayedExpansion the line set "line=%%L" would drop all exclamation marks and also carets (only when exclams are in the line).

That's why I disable the delayed expansion before and only enable it for the two lines, where it is required.

The (echo(!line!) looks strange, but has the advantage, that echo( can display any content in !line! and the outer parenthesis avoids accidentials whitespaces at the line end.

Younker answered 23/1, 2020 at 13:42 Comment(0)
S
1

To convert LF returns to CRLF without causing any tabs to spaces conversion using the more solution, try the find /V command, courtesy of Wikipedia:

find /V "" < input_filename > output_filenam

Like the more answer, this does not do an in-place change. But no external programs needed. The /V says to output any input lines that do not match the pattern of an empty string, and nicely changes the line terminator to the Windows CRLF if needed.

Soyuz answered 25/4, 2023 at 21:34 Comment(0)
S
0

I'm taking an AWS course and have frequently had to copy from text boxes in the AWS web forms to Windows Notepad. So I get the LF-delimited text only on my clipboard. I accidentally discovered that pasting it into my Delphi editor, and then hitting Ctrl+K+W will write the text to a file with CR+LF delimiters. (I'll bet many other IDE editors would do the same).

Splendiferous answered 12/4, 2019 at 20:24 Comment(0)
L
0

Late to the party, but I really needed a short, simple, pure Windows solution. Lots of other answers, but I found FOR /F, MORE, FIND etc all failed in various ingenious ways and I didn't want to use an EXE, Python, VBS, Node, etc. And in these modern times the obvious answer has to be PowerShell. So here is my code.

ls <dir> | %{ (Get-Content $_.FullName) | Set-Content $_.FullName }

Simple huh? Works perfectly with one tiny proviso: it adds a CRLF to the end of the file if there wasn't one. For my purposes that was a bonus, not a problem!

Leet answered 6/9, 2022 at 6:51 Comment(0)
L
-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
Lancey answered 10/7, 2013 at 20:15 Comment(4)
Actually, it would work if he'd simply use something like (for /f "tokens=*" %%a in (%~1) do @echo.%%a)>"%~2".Antiworld
@AnsgarWiechers Yes, this set TargetFile=%2 rem c:\test\out.txt also needs improvement. And, btw, your "tokens=*" also.Varistor
@Varistor REM is a comment in a batch file, you can take out the %1 rem and then give it the specific file you need. As I provided the link, I didn't feel I needed to further document as you were already working with a batch file, correct? Please test it as it does work and it can be integrated into your existing batch files at will. Thanks!Lancey
Works fine for me in Windows 7. I created a file c:\test\test.txt, with EOL from Unix, in Notepad++. Afterwards, I simply ran the batch file. Again, it's not my code, it is code I slightly modified to not display Notepad? I can show the OP how to make it work as opposed to that last comment.Lancey

© 2022 - 2024 — McMap. All rights reserved.