1

I write batch script to find contents for file in folder. Contents are in text file and have special characters like exclamation mark.

How do I get FILENAME and FOLDERNAME which contain exclamation mark.

@ECHO off
SETLOCAL EnableDelayedExpansion

set /p SRC="Enter source folder link: "
set /p DST="Enter destination folder link: "

FOR /F "delims=" %%a IN ('DIR /b /s /a-d "%SRC%"') do (
    Set "CODE=%%~na"
    Set "EXT=%%~xa"
    findstr /c:"!CODE!" "%SRC%\Content.txt">nul
    IF "!errorlevel!" EQU "0" (
        for /F "tokens=2,3" %%c in ('findstr /c:"!CODE!" "%SRC%\Content.txt"') do (
            ECHO !CODE!
            Set "NEWNAME=%%c"
            Set "FOLDERNAME=%%d"
            Set "NEWNAME=!NEWNAME:_= !"
            Set "FOLDERNAME=!FOLDERNAME:_= !"
            IF not exist "%DST%\!FOLDERNAME!" md "%DST%\!FOLDERNAME!"
            mklink "%DST%\!FOLDERNAME!\!NEWNAME!!EXT!" "%%a"
        )
    )
)
Endlocal
Exit

PS: Source folder has many files.

Mofi
  • 46,139
  • 17
  • 80
  • 143
Dang Long
  • 37
  • 1
  • 4

2 Answers2

2

One solution is using a subroutine to avoid usage of delayed environment variable expansion:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

:GetSource
set "SRC="
set /P SRC="Enter source folder link: "
if not defined SRC goto GetSource
set "SRC=%SRC:"=%"
if not defined SRC goto GetSource

:GetDestination
set "DST="
set /P DST="Enter destination folder link: "
if not defined DST goto GetDestination
set "DST=%DST:"=%"
if not defined DST goto GetDestination

for /F "eol=| delims=" %%I in ('dir /A-D /B /S "%SRC%" 2^>nul') do (
    if exist "%SRC%\Content.txt" for /F "tokens=2,3" %%A in ('%SystemRoot%\System32\findstr.exe /C:"%%~nI" "%SRC%\Content.txt" 2^>nul') do (
        set "NEWNAME=%%~A"
        set "FOLDERNAME=%%~B"
        call :MakeLink "%%I"
    )
)

endlocal
exit /B

:MakeLink
echo %~n1
set "NEWNAME=%NEWNAME:_= %"
set "FOLDERNAME=%FOLDERNAME:_= %"
if not exist "%DST%\%FOLDERNAME%" md "%DST%\%FOLDERNAME%"
mklink "%DST%\%FOLDERNAME%\%NEWNAME%%~x1" %1
goto :EOF

Open a command prompt window and run call /? for help explaining how to use the command CALL with enabled command extensions to run a block in same batch file like a subroutine. See also Where does GOTO :EOF return to?

Mofi
  • 46,139
  • 17
  • 80
  • 143
0

I have not studied your code, but I'd assume that enabling the delayed expansion after setting the variable names would be more appropriate:

@Echo Off
SetLocal DisableDelayedExpansion

Set /P "SRC=Enter source folder link: "
Set /P "DST=Enter destination folder link: "

For /D /R %%A In (*) Do For /F "Tokens=2-3" %%B In (
    'FindStr/C:"%%~nxA" "%SRC%\Content.txt" 2^>Nul') Do (Echo %%~nA
    Set "NEW=%%B"
    Set "FLD=%%C"
    SetLocal EnableDelayedExpansion
    If Not Exist "%DST%\!FLD:_= !\" MD "%DST%\!FLD:_= !" 2>Nul && (
        MkLink "%DST%\!FLD:_= !\!NEW:_= !%%~xA" "%%A")
    Endlocal)
Exit /B

I would strongly suggest you perform some proper verification of the user input prior to performing tasks using them, i.e. before the For loop.

Compo
  • 36,585
  • 5
  • 27
  • 39