@echo off
setlocal EnableDelayedExpansion
(for /F "delims=" %%a in (input.txt) do (
set "output="
for /F "delims=" %%b in ('cmd /U /C echo %%a^| find /V ""') do (
set "output=!output! %%b"
)
echo !output:~1!
)) > output.txt
rem Replace the input file for the result
move output.txt input.txt /Y
This solution makes good use of the fact that /U
switch in cmd.exe
creates Unicode output, that is, each input character is converted into two output bytes where the first byte of each pair is a binary zero. These "0-char" pairs are read by find
command that takes each zero as an end-of-line mark. The final result is that the %%b
replaceable parameter in the for
command takes each character of the input lines in a very simple way.
This program eliminate exclamation-marks from the input file; this point may be fixed, if needed.
EDIT: Method modified as reply to comments
I modified the original method so it now manages almost all special characters (excepting quote):
2nd EDIT: I further modified the method following a dbenham's advice and it now manages all characters!
@echo off
setlocal DisableDelayedExpansion
(for /F delims^=^ eol^= %%a in (input.txt) do (
set "str=%%a"
set "output= "
for /F delims^=^ eol^= %%b in ('cmd /V:ON /U /C echo !str!^| find /V ""') do (
setlocal EnableDelayedExpansion
for /F "delims=" %%c in ("!output!") do (
endlocal
set "output=%%c %%b"
)
)
setlocal EnableDelayedExpansion
echo !output:~2!
endlocal
)) > output.txt
rem Replace the input file for the result
move output.txt input.txt /Y
input.txt:
1 7<Y>IO
QU|C"K&7
;T Y!9^0
output.txt:
1 7 < Y > I O
Q U | C " K & 7
; T Y ! 9 ^ 0
If the division in lines would not be needed in the output file, a simpler method could be based on this:
set "output="
for /F eol^= %%b in ('cmd /U /C type input.txt ^| find /V ""') do (
set "output=!output! %%b"
)