Reputation: 123
I have a working batch script that counts .txt files in a directory tree (including subdirectories) then IF the count GTR than 2 basically notifies the user that they must do something before running this script again.
What I would like is for the script when notifying the user to also tell them the filenames of the txt file.
This is what I have.
The following checks the root folder and all sub directories for .txt files. This counts the number of .txt files and sets it.
@echo off & Setlocal
:: Search for files in the Tree
Set "sFolder=C:\folder\folder\root"
Set "sFileType=txt"
set "i=0"
PushD "%sFolder%" &&(
FOR /R "." %%i IN (*) DO ( If /i "%%~xi"==".%sFileType%" ( set /a i+=1 ) ) )
If the count is above 3 goto notify user (which is simple echo commands)
If %i% GTR 2 goto NotifyUser
What I do not get is how I could echo the 3 or more found .txt filenames to the user. I understand it would be a variable but I can't seem to figure it out and how to put it in the above commands.
Also.. on the echoing there are times the filenames may have a " . " in the name more than the extension
IE: filename.txt.gpg
The count command above does NOT count the example filename as a .txt file... but the echoing of the name depending on the command could think this is a txt file ..I do not want the above filename example to echo to the user as one of the counted txt files (since it is NOT counted). (hope that makes sense).
Upvotes: 2
Views: 352
Reputation: 34979
The easiest solution is probably provided in @dbenham's answer. However, I want to give an answer without using a temporary file but (a) variable(s) to store the list of text files.
The following script is based on your for /R
approach and builds up a comma-separated list of found *.txt
files (each one enclosed in ""
) and stores it in the variable ITEMS
. A standard for
loop is used to display the list items in case the amount exceeds the predefined limit. Here it is:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Define constants here:
set "LOCATION=.."
set "PATTERN=*.txt"
set /A LIMIT=2
set /A COUNT=0
set "ITEMS="
pushd "%LOCATION%" && (
for /R "." %%F in ("%PATTERN%") do (
set /A COUNT+=1
set "ITEM=%%~F"
setlocal EnableDelayedExpansion
for /F "delims=" %%S in ("!ITEMS!"!ITEM!",") do (
endlocal
set "ITEMS=%%S"
)
)
popd
)
if %COUNT% GTR %LIMIT% (
echo Cannot continue script, too many "%PATTERN%" files ^(%COUNT%^) encountered:
for %%F in (%ITEMS%) do (
echo(%%~F
)
exit /B
)
rem Continue script here...
endlocal
exit /B
Since the size of an environment variable and ther length of a command line are limited (on Windows 7 x64, 8191 bytes both, I think), this method may fail for a huge number of *.txt
files found.
This script is slightly different and uses array-like variables ITEM[1]
, ITEM[2]
, ITEM[3]
, etc. to store the encountered *.txt
files (one each).
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Define constants here:
set "LOCATION=.."
set "PATTERN=*.txt"
set /A LIMIT=2
set /A COUNT=0
pushd "%LOCATION%" && (
for /R "." %%F in ("%PATTERN%") do (
set /A COUNT+=1
set "ITEM=%%~F"
setlocal EnableDelayedExpansion
for /F "tokens=1,* delims=|" %%S in ("!COUNT!|!ITEM!") do (
endlocal
set "ITEM[%%S]=%%T"
)
)
popd
)
if %COUNT% GTR %LIMIT% (
echo Cannot continue script, too many "%PATTERN%" files ^(%COUNT%^) encountered:
for /L %%F in (1,1,%COUNT%) do (
setlocal EnableDelayedExpansion
echo(!ITEM[%%F]!
endlocal
)
exit /B
)
rem Continue script here...
endlocal
exit /B
Here the environment size (the space holding all of the environment variables) is the limitation; I do not know the limit, but it should be rather high.
Upvotes: 0
Reputation: 130919
You probably don't want to scan for .txt files more than once, so the simplest solution is to store the list of files in a temporary file, and type out the result if and only if the number of lines is greater than 2. You can use FIND to count the lines, and FOR /F to capture the count result.
@echo off
setlocal
set "root=C:\folder\folder\root"
set "out=%temp%\myTextFileList.txt"
dir /b /s /a-d "%root%\*.txt" >"%out%"
for /f %%N in ('find /c /v "" <"%out%"') do if %%N gtr 2 (
echo You cannot proceed because you have more than 2 .TXT files:
type "%out%"
del "%out%"
pause
exit /b
)
del "%out%"
REM Rest of script goes here
Upvotes: 2
Reputation: 129
if all you want to do is echo the names that gave you the total you echoed, you can use this:
@echo off & Setlocal
:: Search for files in the Tree
Set "sFolder=C:\temp"
Set "sFileType=txt"
set "i=0"
PushD "%sFolder%" &&(
FOR /R "." %%i IN (*) DO ( If /i "%%~xi"==".%sFileType%" ( set /a i+=1 &echo %%~ni) ) )
Upvotes: 0