user2150312
user2150312

Reputation: 123

Batch Count .txt Files and echoing filenames after function based on count

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

Answers (3)

aschipfl
aschipfl

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

dbenham
dbenham

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

arana
arana

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

Related Questions