0

I have a script that recursively loops through all .txt files in the working directory and subdirectories and does something with that files. Now I would like to exclude all files in certain subdirectories that are listed in a exclude.txt file:

@ECHO OFF
SETLOCAL EnableDelayedExpansion

for /r %%f in (*.txt) do (
    CALL:processFile %%f %%~df%%~pf
)
GOTO:EOF

:processFile
    SET file_=%~1
    SET path_=%~2                 <- %%~df%%~pf is the full path :(
    find "!path_!" exclude.txt
    IF !ERRORLEVEL! EQU 1 (
        REM do something here
    )
    GOTO:EOF

However, %%/~df%%~pf expands to the absolute path. How can I get the path relative to the workingdirectory? I want to list only the subdirectories in exclude.txt and not the full paths.

PS: I could of course read the relative paths from exclude.txt, append %cd% and write them to some exclude.temp and then search in this temporary file, but I hope there is a nicer way.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • You can't use a GOTO inside a FOR command without breaking it. – Squashman Jan 19 '17 at 16:26
  • Reverse your thought process. Use FINDSTR and use it's /G option. Use the exclude text as your search strings. `echo %%F |findstr /G:exclude.txt`. Regardless of that code change you still can't use GOTO inside your FOR command code block. – Squashman Jan 19 '17 at 16:45
  • @Squashman ups didnt notice, because I am testing the script with a single file only. I changed it, hope it is ok now – 463035818_is_not_an_ai Jan 19 '17 at 16:47
  • Why call out to a label to do that. That just slows down your processing if you have a lot of files to process. Just use the IF command inside your FOR code block. – Squashman Jan 19 '17 at 16:49
  • @Squashman ups sure, I was looking how to use a label inside for and then I didnt realize that I dont need it at all. Edited again. – 463035818_is_not_an_ai Jan 19 '17 at 16:51
  • I gave you the code in my comment. What don't you understand? – Squashman Jan 19 '17 at 16:52
  • in your example code, _(as edited)_, `%%f` is the absolute path including filename which is set as `%file_%` from `%~1`. `%%~df%%~pf` is better written as `%%~dpf` and is the folder including a trailing backslash where the file `%%~nxf` is located. This in your code will be set to `%path_%` from `%~2`. – Compo Jan 19 '17 at 16:54
  • Eliminate current directory in this way: `SET "path_=!path_:*%cd%=!"` – Aacini Jan 19 '17 at 17:00

2 Answers2

3

Give this a try.

@ECHO OFF
SETLOCAL EnableDelayedExpansion

for /r %%F in (*.txt) do (
    echo %%F|findstr /I /G:exclude.txt >nul 2>&1
    IF NOT "!ERRORLEVEL!"=="0" (
        REM do something here
    )
)
Squashman
  • 13,649
  • 5
  • 27
  • 36
1

Here is a different approach, relying on the fact that xcopy is capable of returning relative paths. Since we do not want to copy anything, the /L switch needs to be used (list but do not copy).

for /F "delims=" %%F in ('
    xcopy /L /I /S ".\*.txt" "%TEMP%" ^| find ".\"
') do (
    echo(Relative path to file: "%%~F"

    rem // This block is only needed in case the leading `.\` disturbs:
    set "FILE=%%~F"
    setlocal EnableDelayedExpansion
    echo(Relative path, no `.\`: "!FILE:*.\=!"
    endlocal
)
aschipfl
  • 33,626
  • 12
  • 54
  • 99