ReneGe
asked on
Batch File: FOR /R Copy file with exclamation point in the name
Hi there,
By using a FOR /R command as my provided script, I need to copy files that some times, will have an exclamation mark in the name.
I tried to add an escape code to it, [SET FileName=!FileName:^!=^!!] but I guess I was too ambitious here.
Thanks for your help,
Rene
By using a FOR /R command as my provided script, I need to copy files that some times, will have an exclamation mark in the name.
I tried to add an escape code to it, [SET FileName=!FileName:^!=^!!]
Thanks for your help,
Rene
@echo off
setlocal enabledelayedexpansion
SET SOURCE=C:\Batchfiles\TESTING\1
SET DESTIN=C:\Batchfiles\TESTING\2
for /R "%SOURCE%" %%A in (*.*) do (
SET FileName=%%A
ECHO COPYING !FileName!
COPY /Y "!FileName!" "%DESTIN%"
)
PAUSE
EXIT
For what it's worth, using special characters in Windows file names other than a couple of safe ones like dash, underscore, space can often lead to undesirable consequences in different applications. I typically try and avoid things like slashes, colons, exclamations, percents, etc.
~bp
~bp
ASKER
My challange here is that this script is part of a bigger script that delayed expansion must be enabled.
Let's say it must work with the following script.
Can then delayed expansion be turned off then on within the secong loop, or something?
Thanks,
Rene
Let's say it must work with the following script.
Can then delayed expansion be turned off then on within the secong loop, or something?
Thanks,
Rene
@echo off
SETLOCAL enabledelayedexpansion
SET SOURCE=C:\Batchfiles\TESTING\1
SET DESTIN=C:\Batchfiles\TESTING\2
FOR /L %%A IN (1,1,2) DO (
SET TIMES=%%A
FOR /R "%SOURCE%" %%B IN (*.*) DO (
SET FileName=%%B
ECHO COPYING !TIMES! TIMES: %FileName%
COPY /Y "%FileName%" "%DESTIN%"
)
)
PAUSE
EXIT /B
Why not do it this way?
~bp
~bp
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That should do it!
Thanks bp :~)
Cheers,
Rene
Thanks bp :~)
Cheers,
Rene
Great, thanks.
~bp
~bp
ASKER
Well finally, I'm still challanged with it.
I dont see how I can use the values contained in the variables "SET BasePath_Dest=!BasePath_De st%%A!" without using delayed expansion enabled.
Would you mind giving it a look and give me your feedback?
Thanks,
Rene
I dont see how I can use the values contained in the variables "SET BasePath_Dest=!BasePath_De
Would you mind giving it a look and give me your feedback?
Thanks,
Rene
@echo off
SETLOCAL enabledelayedexpansion
REM SETTING STATIC VARIABLES (TheDate=!Year!-!Month!-!Day!) (TheTime=!Hour!.!Min!.!Sec!)
CALL :GetDateTime "Month" "Day" "Year"
SET TimeStart=%date% %time%
ECHO ^>READING INI FILES
REM for /F "tokens=1,2 delims=^=" %%A in (Settings.ini) do SET Setting.ini_%%A=%%B
SET CounterPath=0
for /F "tokens=1-4 delims=^>" %%A in (Paths.ini) do (
SET /a CounterPath=!CounterPath! + 1
SET BasePathName=%%A
SET BasePath_Source!CounterPath!=%%B
SET BasePath_Dest!CounterPath!=%%C
SET BasePath_Archives!CounterPath!=%%D
)
etc...
FOR /L %%A in (1,1,%CounterPath%) do (
ECHO ------------------------------------------------------------
REM SETUP BASE FOLDERS
SET BasePath_Source=!BasePath_Source%%A!
SET BasePath_Dest=!BasePath_Dest%%A!
SET BasePath_Archives=!BasePath_Archives%%A!\%Year%\%Month%\%Day%-%Hour%h
IF NOT EXIST "!BasePath_Archives!" MD "!BasePath_Archives!"
IF NOT EXIST "!BasePath_Dest!" MD "!BasePath_Dest!"
ECHO COUNTER=%%A BasePath_Source=!BasePath_Source! BasePath_Dest=!BasePath_Dest! BasePath_Archives=!BasePath_Archives!
FOR /F "TOKENS= 2 DELIMS= " %%A IN ('Robocopy "!BasePath_Dest!" "!BasePath_Source!" * /E /MIR /L /NJH /NJS /NS /NDL /XF *.mp3 *.wav *.avi *.wma *.iso /XD ISO "Virtual Machines *" Musique test ^| Findstr -V ^*') DO (
SET PathSource=%%~pA
SET SourceSize=%%~zA
SET FileFull=%%A
SET ZipFile=!BasePath_Archives!%%~spnA.zip
Echo %TheDate%^>%TheTime%^>!SourceSize!^>!FileFull!^>!ZipFile!>>"%File_Archives_Index%"
ECHO.
ECHO ARCHIVING: !FileFull!
ECHO TO: !ZipFile!
"C:\Program Files\7-Zip\7z.exe" a -ppatoF645 -mx=9 "!ZipFile!" "!FileFull!">>"%File_LOG_Archives%_temp.TXT"
SET Result=!errorlevel!
IF !Result! NEQ 0 (
ECHO !Result! ---^> "!FileFull!" >>%File_LOG_ArchivesError%
ECHO ARCHIVE ERROR
) ELSE (
ECHO ARCHIVE COMPLETED
)
)
)
ECHO ^>CLEANING %File_LOG_Archives%
IF EXIST "%File_LOG_Archives%_temp.TXT" (
FOR /F "DELIMS=" %%A IN ('TYPE "%File_LOG_Archives%_temp.TXT" ^| FindStr -i -v "7-Zip 4.65 Copyright" ^| Findstr -i -l -x -v "Scanning"') do echo %%A>>"%File_LOG_Archives%"
)
etc...
In your example above, which file or pathnames could contain exclamation points?
~bp
~bp
ASKER
This portion of the script will archive (zip) files to be later on deleted or updated from the source on a further Robocopy mirroring.
Robocopy will output the file list to -->%%A then --> !FileFull!
Therefore, the files containing the ! are put by users anytime/anywhere in the !BasePath_Source!\*.* /S
Thanks,
Rene
Robocopy will output the file list to -->%%A then --> !FileFull!
Therefore, the files containing the ! are put by users anytime/anywhere in the !BasePath_Source!\*.* /S
Thanks,
Rene
FOR /F "TOKENS= 2 DELIMS= " %%A IN ('Robocopy "!BasePath_Dest!" "!BasePath_Source!" * /E /MIR /L /NJH /NJS /NS /NDL /XF *.mp3 *.wav *.avi *.wma *.iso /XD ISO "Virtual Machines *" Musique test ^| Findstr -V ^*') DO (
SET PathSource=%%~pA
SET SourceSize=%%~zA
SET FileFull=%%A
ASKER
I came up with the following sample working script.
Do you think this should be by best approach?
Thanks & cheers,
Rene
Do you think this should be by best approach?
Thanks & cheers,
Rene
@echo off
SETLOCAL enabledelayedexpansion
SET SOURCE=C:\Batchfiles\TESTING\1
SET DESTIN1=C:\Batchfiles\TESTING\2a
SET DESTIN2=C:\Batchfiles\TESTING\2b
FOR /L %%A IN (1,1,2) DO CALL :CopyFiles "!DESTIN%%A!"
PAUSE
EXIT /B
:CopyFiles
SETLOCAL disabledelayedexpansion
SET DESTIN=%~1
IF NOT EXIST "%DESTIN%" MD "%DESTIN%"
FOR /R "%SOURCE%" %%A IN (*.*) DO (
ECHO COPYING "%%A" TO "%DESTIN%"
COPY /Y "%%A" "%DESTIN%"
)
SETLOCAL enabledelayedexpansion
EXIT /b
How about this approach to keep it even simpler?
~bp
~bp
@ECHO OFF
SET SOURCE=C:\Batchfiles\TESTING\1
SET DESTIN="C:\Batchfiles\TESTING\2a","C:\Batchfiles\TESTING\2b"
FOR %%D IN (%DESTIN%) DO IF NOT EXIST "%%~D" MD "%%~D"
FOR /R "%SOURCE%" %%S IN (*.*) DO (
FOR %%D IN (%DESTIN%) DO (
ECHO COPYING "%%S" TO "%%~D"
COPY /Y "%%S" "%%~D"
)
)
PAUSE
EXIT /B
ASKER
Nice...
Thanks bp !
Cheers,
Rene
Thanks bp !
Cheers,
Rene
In your original example it isn't possible, because the ! never actually gets into the FileName variable. When the statement
SET FileName=%%A
executed, it replaces %%A with it's value, and then proceeds to parse the line. It will see the ! point, and since you have enabled delayed expansion, it treats that as a special character and "eats it up",
For the example you provided, attached is a working solution.
~bp
Open in new window