Я пишу пакетный скрипт, чтобы найти содержимое файла в папке. Содержимое находится в текстовом файле и имеет специальные символы, например восклицательный знак.

Как мне получить FILENAME и FOLDERNAME, содержащие восклицательный знак.

@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: В исходной папке много файлов.

1
Dang Long 25 Сен 2018 в 08:00

2 ответа

Лучший ответ

Одно из решений - использовать подпрограмму, чтобы избежать использования отложенного расширения переменной среды:

@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

Откройте окно командной строки и запустите call /?, чтобы объяснить, как использовать команду CALL с включенными расширениями команд для запуска блока в том же пакетном файле, как подпрограмма. См. Также Куда возвращается GOTO: EOF?

2
Mofi 25 Сен 2018 в 12:06

Я не изучал ваш код, но предполагаю, что включение отложенного расширения после установки имен переменных было бы более подходящим:

@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

Я настоятельно рекомендую вам выполнить некоторую надлежащую проверку вводимых пользователем данных перед выполнением задач с их использованием, то есть перед циклом For.

0
Compo 25 Сен 2018 в 18:12