Page 1 of 1

update to win2unix

Posted: 22 Oct 2012 08:46
by Sponge Belly
Hello All!

Everyone knows this old trick of converting Unix text files to Windows format:

Code: Select all

more unix.txt > win.txt


Btw, more waits for keypress after scrolling 65,534 lines no matter what. But going the other way (from Windows to Unix) is less straightforward. But with a little chicanery and a lot of findstr, I was able to do it.

Type ‘win2unix /?’ for basic usage info. Read the notes for limitations on use.

Code: Select all

@echo off & setlocal enableextensions
if "%~1" neq "/re-enter" goto init
shift /1
if "%~1" neq "" (call :win2unix "%~1") else call :win2unix
goto end

:init
(set lf=^

)
set nl=^^^%lf%%lf%^%lf%%lf%
for /f %%h in (^"/?%nl%/h%nl%/he%nl%/hel%nl%/help^") ^
do if /i "%~1"=="%%h" call :usage && goto end
if "%~2" neq "" (>&2 echo(too many arguments& (call) & goto end)

(call;)

setlocal enabledelayedexpansion
if /i "!cmdcmdline!" neq "!cmdcmdline:%comspec%  /s /d /c=!" ^
set "piped=1"
endlocal & set "piped=%piped%"

if "%~1" neq "" (if exist "%~1\" (>&2 echo("%~1" is a folder
(call) & goto end) else if not exist "%~1" (
>&2 echo(file "%~1" not found& (call) & goto end)
echo("%~1" | findstr "\* \?" >nul && (
>&2 echo(wildcards (* and ?^) not permitted& (call) & goto end)
if "%~z1"=="0" (>&2 echo(file "%~1" is empty& (call) & goto end)
if defined piped (
>&2 echo(specify input from pipe OR file--but not both& (call)
goto end)) else if not defined piped call :usage && goto end

call "%~dpf0" /re-enter "%~1" | findstr /v "^$"

:end
endlocal & goto :EOF

:win2unix
setlocal
if "%~1"=="" (set "file=") else set "file= "%~1""

for /f "delims=" %%i in ('findstr /n "^"%file%') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:*:=!!lf!"
echo(!line!
endlocal
)

endlocal & exit /b 0

:usage
set ^"\n=^^^%lf%%lf%^%lf%%lf%^^"
cls & echo(Converts newlines from Windows to Unix.%nl%%\n%
Usage:%nl%%\n%
  %~n0 win.txt [^> unix.txt]%\n%
  %~n0 win.txt [^| command-name]%\n%
  command-name ^| %~n0 [^> unix.txt]%\n%
  command-name1 ^| %~n0 [^| command-name2]%nl%%\n%
where win.txt has ^<CR^>^<LF^> line-endings and unix.txt ^
uses ^<LF^> for end-of-line.%nl%%\n%
Notes:%\n%
- Writes to Standard Output ^(STDOUT^) by default.%\n%
- Input should be 8-bit ASCII.%\n%
- Null Character (ASCII 0) in input will corrupt output.%\n%
- Cannot process lines longer than approx 8kb.
exit /b 0


Read this blog post for more information.

- SB

Re: DOS to Unix

Posted: 22 Oct 2012 16:54
by foxidrive
This simplifies it a tad:

Syntax: batchfile "file.txt" >"file2.txt"

Code: Select all

@echo off
:init
for /f %%c in ('copy /z "%~dpnx0" nul') do set cr=%%c
(set lf=^

)
del file.tmp 2>nul
for /f "delims=" %%i in ('findstr /n "^" "%~1"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:*:=!!lf!"
echo(!line!
endlocal
)>>file.tmp
setlocal enabledelayedexpansion
findstr /v "!cr!!lf!" file.tmp
endlocal
del file.tmp 2>nul

Re: update to win2unix

Posted: 17 Apr 2013 17:12
by Sponge Belly
Thanks again for the feedback, Mic!

But I’ve updated win2unix yet again (see first post). I’m much happier with this latest version. It traps more errors and is more user-friendly. Read this post on my blog for the whole story.

Btw, I discovered that findstr /v "^$" will do the same job as findstr /v "!cr!!lf!", so no need for delayed expansion.

Hope you find win2unix useful. I’ve learnt a lot from writing it! :-)

- SB

Re: DOS to Unix

Posted: 18 Apr 2013 05:06
by Ed Dyreen
foxidrive wrote:This simplifies it a tad:

Syntax: batchfile "file.txt" >"file2.txt"

Code: Select all

@echo off
:init
for /f %%c in ('copy /z "%~dpnx0" nul') do set cr=%%c
(set lf=^

)
del file.tmp 2>nul
for /f "delims=" %%i in ('findstr /n "^" "%~1"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:*:=!!lf!"
echo(!line!
endlocal
)>>file.tmp
setlocal enabledelayedexpansion
findstr /v "!cr!!lf!" file.tmp
endlocal
del file.tmp 2>nul

Code: Select all

lf%LF%andcrlf%CRLF%lf%LF%andcrlf%CRLF%the end
On XP it produces ( %lf% = linefeed, %crlf% = controlLinefeed )

Code: Select all

lf%LF%andcrlf%LF%lf%LF%andcrlf%LF%the end%LF%%CRLF%C:\myCurrentDir>
Similar problems here

Re: DOS to Unix

Posted: 18 Apr 2013 05:14
by foxidrive
Ed Dyreen wrote:

Code: Select all

lf%LF%andcrlf%CRLF%lf%LF%andcrlf%CRLF%the end
On XP it produces ( %lf% = linefeed, %crlf% = controlLinefeed )

Code: Select all

lf%LF%andcrlf%LF%lf%LF%andcrlf%LF%the end%LF%%CRLF%C:\myCurrentDir>
Similar problems here


I don't follow you Ed. Are you saying that a file with mixed line endings will end up even more mixed up?

Re: update to win2unix

Posted: 18 Apr 2013 06:00
by Ed Dyreen
'
I probably did something wrong, I had to use cmd /k batchfile.cmd "in.txt" >"ou.txt" otherwise it wouldn't produce output ? There is something special, I would expect several crlf's from the echo( but it's somehow replaced succesfully. It's only at the end something goes wrong.

Re: update to win2unix

Posted: 18 Apr 2013 07:23
by carlos
I remember bad, but this:
more unix.txt > win.txt

only converts the final LF at the end of file to CRLF but keep the LF in the middle.?

Re: update to win2unix

Posted: 18 Apr 2013 08:19
by foxidrive
Carlos, I tested it on three lines in a file and they were all converted to CRLF

Re: update to win2unix

Posted: 18 Apr 2013 15:39
by Sponge Belly
FoxiDrive wrote:Carlos, I tested it on three lines in a file and they were all converted to CRLF


And more will end the converted file with CRLF, regardless of what the original file ended with.

- SB