I know there are already a few questions here about this same issue but I am new to batch scripting and I found those solutions hard to apply in my scenario or directly not applying to my script.  

A solution seems to be to temporarily disable `DelayedExpansion` but if I do so then nothing works anymore.

What the script below is trying to accomplish and it works except for the paths with **`!`**, is the following:

It will take a source folder and file by file, including subfolders, check if the file exists in a destination folder. If the file does not exist then it can do two things:

* Copy the file from the source folder to the destination folder, if it is a png, jpg or mp4
* Create a dummy file (a 0 bytes file with the same name and extension) in the destination folder if it is not a `.png`, `.jpg` or `.mp4`. I use for this xcopy (I copy an existing zero bytes file and rename it) because it is the only way I had no issues with special characters.

```bat
@echo off

setlocal EnableExtensions EnableDelayedExpansion 

rem Set the source and destination folders
set "src=L:\folderS\sub1\sub2"
set "dst=L:\folderD\sub1"

rem Set the path to the dummy file that we need to create dummy files with xcopy
set "dummy=L:\dummy.txt"

rem Create the destination folder if it doesn't exist
if not exist "%dst%" mkdir "%dst%"

rem Loop through all the files in the source folder
for /R "%src%" %%f in (*) do (

     rem Get the file path
     set "filePath=%%f"
     echo the full path is !filePath!

     rem Get the file extension
     set "ext=%%~xf"

     rem Get the relative path excluding the path until the specified src folder
     set "relPath=!filePath:%src%\=!"
     echo the relative path is !relPath!

     rem Check if the file does not exist in the destination
     if not exist "%dst%\!relPath!" (

         rem Check if the file extension is png jpg or mp4
         if /I "!ext!" == ".png" (

         rem If the file extension is png jpg or mp4 copy the file and display a message
         rem echo Copying "%%f" to "%dst%\!relPath!"
         xcopy /y "%%f" "%dst%\!relPath!*"

         )else if /I "!ext!" == ".jpg" (
             xcopy /y "%%f" "%dst%\!relPath!*"

         )else if /I "!ext!" == ".mp4" (
             xcopy /y "%%f" "%dst%\!relPath!*"

         )else (

             rem If the file extension is not png jpg or mp4, create a dummy file
             echo Creating dummy "%%f" to "%dst%\!relPath!"

             xcopy /y "%dummy%" "%dst%\!relPath!*"
        )

    )
)
echo Done.

```

The problem seems to be when I store the relative path to the file in relPath, if the filename or any of the subfolders contains a **`!`** then it will ignore everything that goes after the **`!`** but still keeps the file extension somehow. I think, but I am not sure, that even if I would manage to store correctly the path in relPath, I would still have issues when using later on `"%dst%\!relPath!"` in the other parts of the for loop for copying the file or checking if it exists.

How could I get around this?

EDIT: Here is an screenshot showing the result for a very simple scenario:
[![enter image description here](https://i.stack.imgur.com/bBmBV.png)](https://i.stack.imgur.com/bBmBV.png)

EDIT 2:
I tried now with @harrymc suggestion and it seems to have solved partially the issue but some filenames are still giving trouble. New code:

```bat
@echo off

setlocal EnableExtensions EnableDelayedExpansion 

rem Set the source and destination folders
set "src=L:\folderS\sub1\sub2"
set "dst=L:\folderD\sub1"

rem Set the path to the dummy file that we need to create dummy files with xcopy
set "dummy=L:\dummy.txt"

rem Create the destination folder if it doesn't exist
if not exist "%dst%" mkdir "%dst%"

rem Loop through all the files in the source folder
for /R "%src%" %%f in (*) do (

     rem Get the file path
     set "filePath=%%f"
     echo the full path is !filePath!

     rem Get the file extension
     set "ext=%%~xf"

     setlocal EnableExtensions EnableDelayedExpansion
     rem Get the relative path excluding the path until the specified src folder
     set "relPath=!filePath:%src%\=!"
     echo the relative path is !relPath!

     rem Check if the file does not exist in the destination
     if not exist "%dst%\!relPath!" (

         rem Check if the file extension is png jpg or mp4
         if /I "!ext!" == ".png" (

         rem If the file extension is png jpg or mp4 copy the file and display a message
         rem echo Copying "%%f" to "%dst%\!relPath!"
         xcopy /y "%%f" "%dst%\!relPath!*"

         )else if /I "!ext!" == ".jpg" (
             xcopy /y "%%f" "%dst%\!relPath!*"

         )else if /I "!ext!" == ".mp4" (
             xcopy /y "%%f" "%dst%\!relPath!*"

         )else (

             rem If the file extension is not png jpg or mp4, create a dummy file
             echo Creating dummy "%%f" to "%dst%\!relPath!"

             xcopy /y "%dummy%" "%dst%\!relPath!*"
        )

    )
    endlocal
)
echo Done.

```

Here is an example of a filename that still give trouble. I think now this is xcopy limitation due to the length of the filename or maybe another symbol.

[![enter image description here](https://i.stack.imgur.com/NNUma.png)](https://i.stack.imgur.com/NNUma.png)

EDIT 3: It is fully solved now. The last remaining problem was with the lines

```bat
xcopy /y "%%f" "%dst%\!relPath!*"

```

that should instead be:

```bat
echo F|xcopy "!filePath!" "%dst%\!relPath!"

```

this fixed the problem I was still having with some symbols, and with the "F|" xcopy will not ask me each time if it is a file or not.
There is still probably the limitation of 256 chars for xcopy but I don't see to hit that limit. I could instead use robocopy which would be better but robocopy parameters are quite different and I would need probably quite a few attempts to get it right.

Thank you everyone!