1

I have a large batch file that searches %CD% and sub-directory's and ether moves, copies or deletes files of my choosing. I have ran into a problem where the .bat file will pass over files of any type if they have certain symbols in their name like (!,-). Is their a way to have a batch file search %CD% and sub-directory's for files that contain these symbols and rename them with their current name without the symbols? For argument sake lets just use the (!) symbol, and I can edit in the rest. Thank you in advance.

EDIT--------------------------------------------------- Here is part of my code I am using. I do not have one for what I am trying to accomplish at the moment.

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set /p folder1=Folder Name:
set TESTFOLDER=%folder1%
set /p Type=Enter File Type:
set /p copymove=Copy or Move:
set /p directory=DIR:
md "%TESTFOLDER%"

set /a counter=0
FOR /F "tokens=*" %%i IN ('DIR /S /B /A-D "%directory%\""*.%Type%"') DO FOR      /F "tokens=*" %%j IN ('DIR /B "%%i"') DO IF EXIST ".\%TESTFOLDER%\%%j" (
    set /a counter=!counter!+1
    echo folder: %TESTFOLDER%
    %copymove% "%%i" ".\%TESTFOLDER%\"%%j_!counter!.%Type%""
) ELSE %copymove% "%%i" ".\%TESTFOLDER%\%%j"

:eof
  • All I really need is the code to search and rename all files without the symbols. I do not mind it being a separate Batch file, I can always call: it if I have to. – FootBallBat Nov 15 '15 at 16:04
  • Can a known command "CD" use an environmental variable of the same name %CD%. I thought some of the environment variables like %DIR% %DEL% were special in that they set default command line options or other details specific to the command. – Sql Surfer Nov 15 '15 at 16:08
  • Im sorry Wql Surfer you lost me, I have not been making .Bat file for very long but, I'm catching on. So I'm not real sure what you are talking about. – FootBallBat Nov 15 '15 at 16:11

2 Answers2

2

Stay on safe side with proper quoting and delayed expansion disabled:

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set /p "folder1=Folder Name: "
if not defined folder1 set "folder1=33721424"
set "TESTFOLDER=%folder1%"
md "%TESTFOLDER%" 2>NUL

set /p "Type=Enter File Type: "
if not defined type set "type=txt"

rem set /p copymove=Copy or Move:
choice /C CM /M "Copy or Move"
if %errorlevel% EQU 2 (set "copymove=move") else (set "copymove=copy")

set /p "directory=DIR: "
if not defined directory set "directory=D:\bat\Unusual Names" 

FOR /F "delims=" %%i IN ('DIR /S /B /A-D "%directory%\*.%Type%"') DO (
    set "_fileToMove=%%i"
    set "_filename=%%~ni"
    set "_fileexte=%%~xi"
    call :copy_move
)
:endscript
ENDLOCAL
goto :eof

:copy_move
set "_filennew=%_filename%"
set /a "counter=0"
:cmLoop
set /a "counter+=1"
IF EXIST ".\%TESTFOLDER%\%_filennew%%_fileexte%" (
    set "_filennew=%_filename%_%counter%"
    goto :cmLoop
)
echo "%_filennew%%_fileexte%"
%copymove% "%_fileToMove%" ".\%TESTFOLDER%\%_filennew%%_fileexte%" >NUL
goto :eof

Explanation:

  • consistently use %-expansion. All cmd-poisonous characters (e.g. valid folder name and/or extension a&b or c!d) in user's response to set /p (as well as file paths obtained from dir /S /B command) are escaped using double quotes;
  • prevent user's accidentally wrong response cop or even despiteful input 2>NUL del /Q or even del /Q *.* & del to copymove variable, cf. choice and consequent if instead of primitive set /p;
  • FOR /F "delims=" ... as "tokens=*" would remove trailing spaces (although this is not the case of %%i but could be useful in %%j in your original code);
  • omitted inner %%j loop using %%~ni and %%~nxi Parameter Extensions;
  • note that 2>NUL redirection in md "%TESTFOLDER%" 2>NUL suppresses possible A subdirectory or file a already exists error message;
  • analogously, suppressed possible File Not Found message by dir command; note escaped > as 2>NUL in FOR loop command argument;
  • if a file (e.g. abc.txt) exists in target folder, then above above code would copy/move it to first available filename from abc_1.txt, abc_2.txt, abc_3.txt ... sequence;
  • :copy_move subroutine: necessary as using GOTO within parentheses - including FOR and IF commands - will break their context (or even :label as well);
  • :eof label omitted, see goto :eof meaning;
  • if not defined ...: what-if user's response to any of set /P commands would be only hitting Enter?

Output (second run on my ancient data set):

==> D:\bat\SO\33721424.bat
Folder Name:
Enter File Type:
Copy or Move [C,M]?C
DIR:
"01exclam!ation_1.txt"
"02exc!lam!ation_1.txt"
"11per%cent_1.txt"
"12per%cent%_1.txt"
"13per%OS%cent_1.txt"
"14per%%OS%%cent_1.txt"
"15per%3cent_1.txt"
"16per%%3cent_1.txt"
"17per%Gcent_1.txt"
"18per%%Gcent_1.txt"
"21ampers&nd_1.txt"
"21ampers^&nd_1.txt"
"22ampers&&nd_1.txt"
"22ampers^&^&nd_1.txt"
"31(left_parenthesis_1.txt"
"32(both)parentheses_1.txt"
"32_rght)parenthesis_1.txt"
"41a~tilde_1.txt"
"51a^caret_1.txt"
"AÄaá^ cč^DĎ(1!)&°~!.foo~bar_1.txt"
"AÄzž^ yýS%OS%Š%%OS%%(%1!)&°~%%G!^%~2.foo~bar_1.txt"
"BÄaá^ cčD%OS%Ď%%OS%%(%1!)&°~%%G!^%~2.foo~bar_1.txt"
"elpfile_2.txt"
"new - 01exclam!ation_1.txt"
"scripts‹lpfile.txt"
"Unicode the flag or check_1.txt"
"Unicode the ⚑ or ✔ char_1.txt"
"elpfile_3.txt"

==>
Community
  • 1
  • 1
JosefZ
  • 28,460
  • 5
  • 44
  • 83
  • It fails with '!' or '^' in the filename – jeb Nov 16 '15 at 08:45
  • Nice, now it seems to be bullet proof – jeb Nov 16 '15 at 15:16
  • @jeb I know that there is unsafe `md "%TESTFOLDER%"`. Would not create a folder if there is a **file of the same name**, e.g. `type nul>"%TESTFOLDER%"` :) Maybe an additional test could help: `if not exist "%TESTFOLDER%\" goto :invalidTestFolder`. – JosefZ Nov 16 '15 at 15:32
0

Remove SETLOCAL ENABLEDELAYEDEXPANSION and instead use call to expand counter variable:

set /a counter+=1
call %copymove% "%%i" ".\%TESTFOLDER%\%%j_%%counter%%.%Type%"
wOxxOm
  • 65,848
  • 11
  • 132
  • 136