user2980060
user2980060

Reputation: 131

Convert all CR to CRLF in text file using CMD

Is there a way to convert all CRs to CRLFs in a text file?

When I open a text file from Linux server on Windows, all text is displayed in one line, but actually it's a multi line one.

I'd like to perform the conversion in a batch file.

Can anyone advice, please?

Upvotes: 12

Views: 53709

Answers (7)

aschipfl
aschipfl

Reputation: 34979

A possible though quite cumbersome way is to use CertUtil.exe, an executable that is natively included since past Windows XP, if I remember correctly. Here is a possible script (let us call it conv-eol.bat; see all the explanatory rem remarks in the code):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_IFILE=%~1"  & rem // (input file; first command line argument)
set "_OFILE=%~2"  & rem // (output file; second command line argument)
set "_IEOL=0d"    & rem // (incoming line-breaks; `0d` or `0a`)
set "_OEOL=0d 0a" & rem // (outgoing line-breaks; `0d`, `0a`, `0d 0a`, ``)
set "_TFILE1=%TEMP%\%~n0_%RANDOM%.hex" & rem // (first temporary file)
set "_TFILE2=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (second temporary file)

rem // Verify input file:
< "%_IFILE%" rem/ || exit /B
rem // Convert input file to hexadecimal values (first temporary file):
CertUtil -f -encodehex "%_IFILE%" "%_TFILE1%" 4 > nul
rem // Write to second temporary file:
> "%_TFILE2%" (
    setlocal EnableDelayedExpansion
    rem // Read first temporary file line by line:
    for /F "usebackq delims=" %%L in ("!_TFILE1!") do (
        rem /* Store current line (hex. values), then replace line-breaks
        rem    using the given line-break codes and return result: */
        set "LINE=%%L" & echo(!LINE:%_IEOL%=%_OEOL%!
    )
    endlocal
)
rem // Verify output file:
> "%_OFILE%" rem/ || exit /B
rem // Convert second temporary file back to text into output file:
CertUtil -f -decodehex "%_TFILE2%" "%_OFILE%" 4 > nul
rem // Clean up temporary files:
del "%_TFILE1%" "%_TFILE2%"

endlocal
exit /B

Provide the input file as the first command line argument and the output file as the second one to the script (they may even equal):

conv-eol.bat "input-file.txt" "output-file.txt"

The input and output line-breaks must be specified as hexadecimal character codes, while 0d represents the carriage-return (CR) and 0a the line-feed (LF) character.

The following table tells how to set the variables _IEOL and _OEOL at the top of the script for different line-break style conversion tasks:

from       \       to||Mac (CR)             ||Unix/Linux (LF)      ||DOS/Windows (CR+LF)  
Mac (CR)             ||#####################||_IEOL=0d, _OEOL=0a   ||_IEOL=0d, _OEOL=0d 0a
Unix/Linux (LF)      ||_IEOL=0a, _OEOL=0d   ||#####################||_IEOL=0a, _OEOL=0d 0a
DOS/Windows (CR+LF)  ||_IEOL=0a, _OEOL=     ||_IEOL=0d, _OEOL=     ||#####################

Upvotes: 3

staafl
staafl

Reputation: 3235

The following batch fragment does the trick:

del outputfile
for /f "delims=" %%x in (inputfile) do echo %%x>>outputfile

Its advantage is not relying on the find program, which is rather temperamental (hangs or doesn't work on some machines where I tested the other solutions).

Upvotes: 1

user9389528
user9389528

Reputation: 1

One ridiculous way. Works with the following scenarios:

  1. Text file with a CR at end of every line.
  2. Text file with a repeating set of CR at end of line followed by an empty line with CRLF. Good luck!

Open the file in Notepad++ (free app) and set View -> All Characters.

IF all lines end in CR then:

  1. Open in Microsoft Wordpad - NOT - Word and save the file in MSDOS-Format. ELSE IF lines end in CR followed by a blank line ending with CRLF then
  2. remove the blank lines first with Notepad++. Go to Edit -> Line Operations -> Remove empty lines and save the file.
  3. Open the file in Microsoft Wordpad and save in MSDOS-Format.

END IF

Upvotes: 0

Graeme Cree
Graeme Cree

Reputation: 1

In Windows XP and earlier, you can convert a text file to CRLF simply by opening and saving it in Dos Edit (or Windows Edit). Unfortunately, the Edit program was removed in Vista.

Upvotes: 0

anonymous
anonymous

Reputation: 21

cat file | perl -pe 's/\R/\n/g'

Upvotes: 1

RBerteig
RBerteig

Reputation: 43366

Line separators and line terminators have been a source of compatibility friction between systems as long as there has been more than one kind of system and an urge to exchange data. The Wikipedia article on the Newline has a decent overview of the historical context. And, it suggests a variety of solutions to this problem specifically for use on the Unix side or the Windows side.

On the Unix (Linux) side, look for a utility named unix2dos and its close relative dos2unix. These are commonly available, either as a component of a commercial Unix or as open source tools. If available, they are the best answer because they (usually, see your verson's man pages for details) are careful about files that are accidentally written with both line endings. In that unfortunate case, a trip through both utilities will usually clean up the file to be internally consistent. In the absence of these convenient commands, many native utilities can be made to do the conversion. For instance, converting DOS CRLF line endings to Unix newlines can be done with the tr command:

$ tr -d '\r' < inputfile > outputfile

But do note the caveat that this command assumed that all lines were terminated by CRLF (or LFCR) and works by simply deleting every CR character from the input. Any naked CR characters will be lost.

On the DOS and Windows side, it used to be a lot bleaker. Ports of unix2dos and dos2unix certainly exist, for instance they are included in the much larger Cygwin tools that provide a complete unix emulation on a Windows machine. But a solution using only built-in features was hard to find.

Modern Windows (probably since Windows XP), however, is better. There, the built-in FIND command is much less touchy about choice of line terminator than it used to be, and can be used to do the required conversion from Unix line endings to DOS endings. The Wiki page cited above gives this recipe:

C:\...> TYPE filename.u | FIND "" /V >filename.txt

Experimentation shows that this works as well, but it may not give identical results for unknown reasons:

C:\...> FIND "" /V <filename.u >filename.txt

In both cases, you create a copy of the file with the changed line endings. It would probably not be recommended to change the files in place.

I'll mention one other approach that always seems tempting on paper. When you use Samba to provide the file system share on the Linux server for mounting by Windows, there is a configuration option you can set for the share that mounts it in "text mode". Shares mounted in "text mode" automatically have line endings converted. If it works for you, that is probably the cleanest possible solution. Both systems use their preferred text file format, and neither has to fuss about it. But test carefully, this solution is full of edge cases and pitfalls. Most importantly, don't expect binary files on a text mode file system mount point to read correctly. They often will, but not necessarily always.

Upvotes: 17

MC ND
MC ND

Reputation: 70941

type inputfile | find /v "" > outputfile

That should do it. type reads input file and pipes output to find with parameters to match all lines and output them to output file. In the process, LF is converted to CRLF

Upvotes: 7

Related Questions