Convert Unix Line Endings to Windows for Compatibility
Learn to convert Unix line endings to Windows for file compatibility, fix LF vs CRLF errors, and stop Git warnings. Practical commands and a free tool.
Convert Unix Line Endings to Windows for File Compatibility
You opened a file in Notepad and every line ran together into one long wall of text. Or a legacy Windows importer choked on a .csv that looked perfect on your Mac. Both problems trace to the same cause, and converting Unix line endings to Windows for file compatibility fixes both.
The difference is one invisible byte. Unix ends a line with a single line feed, \n. Windows ends it with a carriage return plus a line feed, \r\n. When a Windows tool that expects \r\n reads a file that only has \n, it may see no line breaks at all. The rest of this post shows how to convert LF to CRLF line endings by hand, by command line, and in bulk.
Unix vs Windows Line Endings Explained
A line ending is a control character, not a visible one. Three conventions exist, and only two matter today.
Unix and modern macOS use LF, the line feed byte 0x0A, written \n.
Windows uses CRLF, a carriage return 0x0D followed by a line feed, written \r\n.
Classic Mac OS used a bare CR, but you will almost never meet it anymore.
The Unix vs Windows line endings difference is a holdover from typewriters, where a carriage return moved the print head back and a line feed rolled the paper up. Unix collapsed both actions into one byte; Windows kept both. Neither is wrong, but a file carrying the wrong one for its destination reads as broken.
What Causes Line Ending Mismatch Errors
The trouble starts when a file crosses between systems. A script written on Linux, a database export from a Mac, or a config file pulled from a Docker container all arrive on Windows with LF endings.
Knowing what causes line ending mismatch errors saves hours of confused debugging. Watch for these signals.
Notepad shows the whole file on one line, because it only breaks on CRLF and sees no \r.
A Windows batch script or older parser reads past line boundaries and fails on "unexpected end of input."
A .bat or PowerShell script fails silently or runs the wrong command because a trailing \r sticks to an argument.
Diff tools mark every single line as changed, since one file uses LF and the other CRLF, even when the visible text is identical.
That last one is the tell. When a diff lights up entirely red and green but the words look the same, you are looking at a line ending mismatch, not a real edit.
Convert Unix Line Endings to Windows in the Browser
The fastest fix for a single file needs no install and no command line. Paste the text, get CRLF-terminated output, copy it back.
For a quick cleanup pass, the Plain Text Formatter and Remove Extra Spaces tools normalize stray whitespace and line breaks in copy-pasted content, which clears up the most common "why does this paste look wrong" cases before they reach a fussy Windows importer. Everything runs in your browser, so the file never leaves your machine.
Prefer to see the raw bytes change? A one-line sed command converts LF to CRLF in place:
# Add a carriage return before every line feed
sed -i 's/$/\r/' unix-file.txt
The s/$/\r/ substitution matches the end of each line and inserts \r, turning \n into \r\n. Run it twice and you get double carriage returns, so apply it only to a file you know is currently LF-only.
To detect the line ending format in a text file before you touch it, file and cat tell you plainly:
file unix-file.txt
# unix-file.txt: ASCII text <- LF endings
# unix-file.txt: ASCII text, with CRLF line terminators <- already CRLF
cat -A unix-file.txt | head -1
# line one$ <- $ alone means LF
# line one^M$ <- ^M$ means CRLF
The ^M in cat -A output is the carriage return. See it and the file already has Windows endings; see a bare $ and you need to convert.
The Cleanest Way to Convert LF to CRLF Line Endings
For anything beyond a one-off, unix2dos is the purpose-built tool. It ships with most Linux distributions and installs on macOS through Homebrew with brew install dos2unix.
Convert a single file to Windows endings:
unix2dos report.txt
# unix2dos: converting file report.txt to DOS format...
Going the other direction, dos2unix report.txt strips the carriage returns back to LF. Both commands rewrite the file in place and are safe to run repeatedly, since they detect the current format first. That idempotence is what makes unix2dos the best free line ending converter tool for scripted pipelines: rerunning it never doubles the endings the way a naive sed does.
If you would rather not install anything, Python does the same job in a way that runs identically on every platform:
with open("report.txt", "rb") as f:
data = f.read()
# Normalize any mix of endings to LF first, then to CRLF
data = data.replace(b"\r\n", b"\n").replace(b"\n", b"\r\n")
with open("report.txt", "wb") as f:
f.write(data)
Opening in binary mode (rb and wb) matters. It stops Python from silently translating endings on your behalf, so you control exactly what the script writes. The two-step replace normalizes a mixed file to LF, then promotes every LF to CRLF, which avoids the double-carriage-return trap.
Batch Convert Line Endings for Multiple Files
One file is a paste. A whole repository of exports is a loop. To batch convert line endings for multiple files, point unix2dos at a filtered file list:
# Convert every .txt and .csv under the current directory to CRLF
find . -type f \( -name "*.txt" -o -name "*.csv" \) -exec unix2dos {} +
The find ... -exec pattern hands each matching file to unix2dos in batches. Scope the -name filters tightly, because converting a binary file or an image to CRLF corrupts it by rewriting byte sequences that were never line endings.
Skip your .git directory and any node_modules when you run a sweep like this. A blanket conversion across a project will happily mangle packed Git objects and vendored binaries if you let it.
Fix Git Line Ending Warnings on Windows
Git is where line endings cause the most day-to-day friction. Clone a repo on Windows and you may see warning: LF will be replaced by CRLF, then a diff claiming you changed every line you never touched.
The durable fix lives in a .gitattributes file at the repo root, which pins each file type's endings for everyone regardless of their OS:
# .gitattributes
* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.png binary
text=auto lets Git normalize text to LF in the repository while checking out the platform-native ending. The explicit rules force shell scripts to stay LF (they break on Windows CRLF) and batch files to stay CRLF, and mark PNGs binary so Git never touches them.
To fix Git line ending warnings on Windows without editing every developer's config, commit that .gitattributes, then renormalize once:
git add --renormalize .
git commit -m "Normalize line endings via .gitattributes"
That single commit rewrites the stored endings to match your rules, and the phantom "every line changed" diffs stop for the whole team.
Get Your Files Talking Again
Convert Unix line endings to Windows for file compatibility whenever a .txt, .csv, or script that looks fine on Linux arrives broken on Windows. Detect the current format with file or cat -A, convert with unix2dos or a binary-mode Python pass, and pin the outcome in .gitattributes so it never regresses.
For a quick browser cleanup of pasted text with tangled spaces and line breaks, reach for the free Plain Text Formatter. Working with structured data instead? The JSON Formatter validates and pretty-prints in your browser, no upload and no signup, so a stray carriage return never silently breaks your next import.
Ready to try it yourself?
Browse Free Tools →