Code: Select all
@echo off
:loop
FOR %%G IN ("* *.txt") DO (
FOR /F "tokens=1* delims= " %%H IN ("%%~G") DO (
IF NOT "%%~I"=="" (
rename "%%~G" "%%~H_%%~I"
goto loop
)
)
)
Moderator: DosItHelp
Code: Select all
@echo off
:loop
FOR %%G IN ("* *.txt") DO (
FOR /F "tokens=1* delims= " %%H IN ("%%~G") DO (
IF NOT "%%~I"=="" (
rename "%%~G" "%%~H_%%~I"
goto loop
)
)
)
Code: Select all
cmd /c "@(call &for %F in ("* *.txt") do @for /f "tokens=1* delims= " %A in ("%F") do @if not "%B"=="" (ren "%F" "%A_%B"&call))&if not errorlevel 1 %^cmdcmdline%"
Code: Select all
'%cmdcmdline%' is not recognized as an internal or external command,
operable program or batch file.
Code: Select all
@cmd /c "(call &for %%F in (%*) do @for /f "tokens=1* delims= " %%A in ("%%F") do @if not "%%B"=="" (ren "%%F" "%%A_%%B"&call))&if not errorlevel 1 %%cmdcmdline%%"
Code: Select all
renSpaceTo_ *.bat *.exe
Code: Select all
doskey renSpaceTo_=cmd /c "@(call &for %F in ($*) do @for /f "tokens=1* delims= " %A in ("%F") do @if not "%B"=="" (ren "%F" "%A_%B"&call))&if not errorlevel 1 %^cmdcmdline%"
Code: Select all
C:\test>doskey /macros
renSpaceTo_=cmd /c "@(call &for %F in ($*) do @for /f "tokens=1* delims= " %A in ("%F") do @if not "%B"==" (ren "%F" "%A_%B"&call))&if not errorlevel 1 %^cmdcmdline%"
Code: Select all
doskey renSpaceTo_=cmd /c "@(call &for %F in ($*) do @for /f "tokens=1* delims= " %A in ("%F") do @if not "%B"=="""" (ren "%F" "%A_%B"&call))&if not errorlevel 1 %^cmdcmdline%"
It's quite likely that the FOR loop was implemented using FindFirstFile and FindNextFile. These functions work with file handles and won't process the same file twice. Also the order of the found files isn't necessarily alphabetic. It's rather depending on the file system. E.g. on FAT file systems the files are enumerated in the order they have been added to the FAT file table.
Code: Select all
@echo off &setlocal
for /l %%i in (1 1 5000) do >"%%i.txt" type nul
for %%i in (*.txt) do (
echo ren "%%i" "X%%i"
ren "%%i" "X%%i"
)
pause
I was originally just testing with two files that were named the same with multiple spaces except for a 1 and 2 at the end of the base file name. The file1 would get two of the spaces changed but file2 would only get one space changed.dbenham wrote: ↑21 Jun 2018 13:44Actually the simple FOR statement uses some form of buffering. If all of the matching files fit within the buffer, then newly appearing file names will never be processed. But if there are a lot of files, then the first set of files that fit in the buffer are processed. Then when the next set of files is loaded into the buffer, newly appearing file names may be included, depending on the sort order.
Dave Benham
Code: Select all
C:\Users\Squashman\spaces>dir /b
fu bar 1.txt
s p aces.txt
C:\Users\Squashman\spaces>renSpaceTo_ *.txt
C:\Users\Squashman\spaces>dir /b
fu_bar_1.txt
s_p aces.txt
C:\Users\Squashman\spaces>doskey /macros
renSpaceTo_=cmd /c "@(call &for %F in ($*) do @for /f "tokens=1* delims= " %A in ("%F") do @if not "%B"=="" (ren "%F" "%A_%B"&call))&if not errorlevel 1 %^cmdcmdline%"
Code: Select all
// addx.c
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main(void)
{
wchar_t buf[MAX_PATH] = {'X'};
WIN32_FIND_DATAW finddata = {0};
HANDLE f = FindFirstFileW(L"*.txt", &finddata);
if (f == INVALID_HANDLE_VALUE)
return 1;
do
{
wcsncpy(&buf[1], finddata.cFileName, MAX_PATH - 1);
wprintf(L"ren %s %s\n", finddata.cFileName, buf);
MoveFileExW(finddata.cFileName, buf, MOVEFILE_REPLACE_EXISTING);
} while (FindNextFileW(f, &finddata) != FALSE);
FindClose(f);
return 0;
}
That is weirdSquashman wrote: ↑21 Jun 2018 14:38I gave the doskey macro a try.
This was my results.Code: Select all
C:\Users\Squashman\spaces>dir /b fu bar 1.txt s p aces.txt C:\Users\Squashman\spaces>renSpaceTo_ *.txt C:\Users\Squashman\spaces>dir /b fu_bar_1.txt s_p aces.txt C:\Users\Squashman\spaces>doskey /macros renSpaceTo_=cmd /c "@(call &for %F in ($*) do @for /f "tokens=1* delims= " %A in ("%F") do @if not "%B"=="" (ren "%F" "%A_%B"&call))&if not errorlevel 1 %^cmdcmdline%"
Code: Select all
@cmd /c "for /l %%. in () do @(call&for %%F in (%*) do @for /f "tokens=1* delims= " %%A in ("%%~F") do @if not "%%B"=="" (ren "%%~F" "%%A_%%B"&&call ))&if errorlevel 1 exit 0"
Code: Select all
doskey renSpaceTo_=cmd /c "for /l %. in () do @(call&for %F in ($*) do @for /f "tokens=1* delims= " %A in ("%~F") do @if not "%B"=="""" (ren "%~F" "%A_%B"&&call ))&if errorlevel 1 exit 0"
Code: Select all
@cmd /c "for /l %%. in () do @(call&for %%F in (%*) do @for /f "tokens=1* delims= " %%A in ("%%~F") do @if not "%%B"=="" ren "%%~F" "%%A_%%B")&if errorlevel 1 exit 0"
Code: Select all
doskey renSpaceTo_=cmd /c "for /l %. in () do @(call&for %F in ($*) do @for /f "tokens=1* delims= " %A in ("%~F") do @if not "%B"=="""" ren "%~F" "%A_%B")&if errorlevel 1 exit 0"
This is right.
Code: Select all
@echo off
setlocal
call :set.printErrorLine
ren . .
%ID-1:##==1%
set prompt=$g$s
set "X= "
set "Y=_"
set hide= @
set /a tests=1
md testdirRen
pushd testdirRen
for %%i in ("fil e 2 1 4 and so on with xx"
"fi xy zu drxzbu z543 6gg hg feeev lll juz tre ghj lk 0"
"test 3 4 5 6"
"test 4 4 5 6"
"test 5 4 5 6"
) do >%%i.txt echo
call :test1
popD
rd /s /q testdirRen
pause
exit /b
:test1
set /a loop#=0
%ID-1:##==2%
set "M="
call :rename1 %hide% rem rem rem rem rem rem
echo(
2>nul set /a Htest=1/(tests%%2) || set "hide=rem %hide%"
set /a tests+=1
( set "X=%Y%"
set "Y=%X%" )
if %tests% leq 14 goto :test1
:test2
set /a loop#=0
echo --- with Variable
call :rename2
set /a tests+=1
( set "X=%Y%"
set "Y=%X%" )
if %tests% leq 16 goto :test2
:test3
set /a loop#=0
echo --- with Parameter
call :rename3 "*%X%*.txt"
set /a tests+=1
( set "X=%Y%"
set "Y=%X%" )
if %tests% leq 18 goto :test3
exit /b
:rename3
set /a loop#+=1
if NOT exist "%~1" exit /b
for /f "tokens=1*delims=%X%" %%i in ("%~nx1") do ( echo loop# %loop#% ren ^>^>^> "%%i%Y%%%j"
ren "%~f1" "%%i%Y%%%j"
)
goto %0
exit /b
:rename1
set /a loop#+=1
%M% %1 echo --- in for /f -if exist "File*%X%*name" goto %0
%M% %2 echo --- in for /f -if exist "File*%X%*name" call %0 stackError "_" ^> " "
%M% %3 echo --- in for /f -call %0
%M% %4 echo --- in for loop -if exist "*%X%*" goto %0
%M% %5 echo --- in for loop -if exist "*%X%*" call %0
%M% %6 echo --- in for loop -call %0
%M% %7 echo --- behind for loop if exist "*%X%*" goto %0
set "M=:: "
(
for %%i in ("*%X%*.txt") do (
for /f "tokens=1*delims=%X%" %%j in ("%%~i") do (
if "%%k" neq "" ( echo loop# %loop#% ^>^>^> %%j^%Y%%%k
ren "%%i" "%%j%Y%%%k"
if errorlevel 1 echo ERROR -- %%i %== when NOT leave the for stack this will happen ==%
%1 if exist "%%j%Y%*%X%*%%~xk" goto %0 %== exit every loop ==%
%2 if exist "%%j%Y%*%X%*%%~xk" call %0 %* %== leave NOT the for stack ==%
%3 call %0 %* %== leave the FOR stack ==%
))
%4 if exist "*%X%*.txt" goto %0
%5 if exist "*%X%*" call %0 %*
%6 call %0 %*
)
echo END Loop# %loop#%
)
%7 if exist "*%X%*.txt" goto %0 %== get as rounds as max rename sign in filename ==%
exit /b
:rename2
setlocal enabledelayedexpansion
for %%i in ("*%X%*.txt") do ( set "filename=%%i"
echo ren ^>^>^> "!filename:%X%=%Y%!"
ren "%%i" "!filename:%X%=%Y%!"
)
exit /b
:set.printErrorLine
rem Read the fullline BEFORE into Variables with LineNumber; do something ...
rem usage: command 1 line before
rem %%ID-1:##==uniqueString%% [& command %%L ... %%M ...]
set ID-1= @ if errorlevel 1 for /f "usebackQtokens=1*delims=:" %%L in (^
`cmd /v /c ^"findstr /nrc:"^!CLString^!ID-1:.#^=^##%%" "%~f0"^"`) do ^>^&2 echo BatchLine: %%L -- %%M
for %%L in (^"^
%== create CR LF searchstring ==%
) do for /f %%C in ('copy /z "%~f0" nul') do set "CLString=..*%%C*%%~L.*"
exit /b