Find multiple string matches from the original string batch script - batch-file

I currently have a list of files in a folder that i need to iterate through and exclude the non production files that matches the pattern. how do i search for multiple strings in a batch command?
for example i have files as
QA_test_1.txt
QA_809_test.txt
dev_93439_sd.txt
stg_abc_sldkf_df.txt
prod_4845_sdfd.txt
prod_998_sdfd.txt
live_lskd_sd3434.txt
xyz_sdfdf_s3rer.txt
from the list above i need to exclude every file that has the word "dev", QA "Stg" and generate a list of files without them - which is
prod_4845_sdfd.txt
prod_998_sdfd.txt
live_lskd_sd3434.txt
xyz_sdfdf_s3rer.txt
The problem is - i am not able to find any batch command that can do a grep equivalent for multiple strings. FindStr does it only for one string and hence i am not able to get that working. here is code that i have
set i=0
for /F "delims=" %%a in ('dir /B /A /S Path *.txt') do (
set /A i+=1
rem put the file names in array
set list[!i!]=%%~na
rem try to find the file names
echo %%~na|find "dev" or "qa" or "stg" >nul
if errorlevel 1 (echo notfound) else (echo found %%~na )
)

Thank you for all the response.
I was able to do it below way
echo %%~na|findstr /i /v "dev QA Stg" >nul
if errorlevel 1 (echo not found %%~na) else (echo %%~na>>newfile.txt)

Related

Comparing the contents of two recently created folders using Windows Batch file

I'm writing a batch file to compare the contents of two folders on a network drive. A new folder is generated every night by a macro and I want to see what changed between today and yesterday. For example, if yesterday's folder is called "B" and today's folder is "A" and their structure looks like:
- Home
- A
- file1.txt
- file2.txt
- file4.txt
- B
- file1.txt
- file2.txt
- file3.txt
I would want to see something like
A: file4.txt added
A: file3.txt removed
But the format of the output doesn't really matter at the end of the day. I just need to see a comparison of the folder's contents.
What I have so far
Using my limited batch knowledge, I've smashed together this currently non-working solution:
#ECHO OFF
setlocal EnableDelayedExpansion
pushd "\\domain\path\to\Home"
set "j=0"
set "count=2"
:: get the names of the two most recently added folders
FOR /f "delims=" %%i IN ('dir /AD-H /B /O-D') DO (
set /A j=j+1
if !j! equ 1 (
:: send contents of newest folder to file
dir !i! /B > newest_folder.txt
)
if !j! equ 2 (
:: send contents of second-newest folder to file
dir !i! /B > older_folder.txt
)
if !j! geq !count! (
:: break after two folders
goto :end
)
)
:end
fc newest_folder.txt oldest_folder.txt
PAUSE
I saw a similar solution here:
(for %%i in ("folder2\*") do if exist "folder1\%%~nxi" echo(%%~i)>file.csv
But it wouldn't work in my case because the folder names change every day.
Any help would be appreciated!
#ECHO OFF
setlocal EnableDelayedExpansion
set "later="
set "earlier="
pushd "\\domain\path\to\Home"
:: get the names of the two most recently added folders
FOR /f "delims=" %%i IN ('dir /AD-H /B /O-D') DO (
if defined later set "earlier=%%i"&goto report
set "later=%%i"
)
:report
if defined earlier (
dir /b "%earlier%">older.txt
dir /b "%later%">newer.txt
fc older.txt newer.txt
) else echo too few directories found
pause
popd
would be my approach, setting later and earlier to the names of the first two directories found by the dir command.
---- afterthought
if the fc command is replaced by
echo files added
findstr /x /v /g:"older.txt" "newer.txt"
echo files deleted
findstr /x /v /g:"newer.txt" "older.txt"
then your report should be more easily interpreted.
findstr options /x does an exact match, /v reports NON-matches and /g:filename specifies a file containing strings against which to match.

Counting files in a folder in a batch file doesn't work as expected

I'm having trouble when counting files in a specific folder in a batch file.
My folder at C:\logs contains seven different log files.
When I run the batch file with the following content, I'm always getting "1" as the value for COUNT:
SETLOCAL ENABLEDELAYEDEXPANSION
SET LOGS_LOCAL=C:\logs
SET COUNT=0
REM Count logs
for %%A in ("%LOGS_LOCAL%") do set /a COUNT+=1
echo !COUNT!
pause
As you can see I used the snippet of an answer from this question but it still doesn't work.
What am I doing wrong? Do I need to change any other settings?
just to show you a different way:
for /f %%a in ('dir /b /a-d ^|find /c /v ""') do set count=%%a
echo %count%
dir parameters:
/b use simple format (names only, no summary, no header)
/a-d exclude folders (show files only)
find /c /v "" then just counts the entries (/c = count, /v "" = every non-empty line)
I experimented a bit and it seems that one must specify the wanted files exactly. I changed the path of my log folder from
SET LOGS_LOCAL=C:\Backups\weekly\logs
to
SET LOGS_LOCAL=C:\Backups\weekly\logs\*.log
Now, my batch file returns "7" for COUNT.
You're SETting 1 single directory, C:\logs, as your variable, LOGS_LOCAL, so the COUNT is working correctly with its output result of 1.
What I think you intended to do count files within that directory like this:
#ECHO OFF
SET "LOGS_LOCAL=C:\logs"
SET "COUNT=0"
REM Count logs
FOR %%A IN ("%LOGS_LOCAL%\*.log") DO SET/A COUNT+=1
ECHO %COUNT%
PAUSE

batch pick random file that contains utf-8 characters in its name

I want to open a random file in a directory and its subdirectorys with batch. And I know there are enough questions on stackoverflow who give the code for that but none of which I found were with utf-8 character support.
I use the following code which I found in stackoverflow.
#echo off
setlocal
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"
:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N
call :openRandomFile
:: Delete the temp file
del "%tempFile%"
exit /b
:openRandomFile
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
'findstr "^%randomNum%:" "%tempFile%"'
) do start "" "%%B"
cmd /k
It works fine that way, until it picks a file like "blablabla_空色デイズ.mp3", in that case it gives an error like "file blablabla_?????.mp3 could not be found." and I have dozens of these files.
I have tried using chcp 65001 on the start of the file for using utf-8 and if I did so, the teporary created .txt list shows the correct names of japanese files, but the pick up itself does not work anymore after that, so I took away #echo off and cmd prints an error on set /a "randomNum=(%random% %% cnt) + 1": Error: division by zero.
And at this point, I dont understand anymore whats going on, because the file is working great without chcp 65001.
I don't know batch, please, does anyone have an idea how to make it run?
I would be really happy!
You will have a lot of problems with findstr and command output when utf8/unicode characters are involved. In this type of scenarios it is safer (but slower) to avoid them
#echo off
setlocal enableextensions disabledelayedexpansion
rem %1 = folder where to start to list files
rem if empty, current active directory is used
rem %2 = file mask
rem if empty * is used
rem What to search
set "fileMask=%~2" & if not defined fileMask set "fileMask=*"
rem Retrieve the number of matching files
set "nFiles=0" & for /r "%~f1." %%a in ("%fileMask%") do set /a "nFiles+=1"
if %nFiles% lss 1 exit /b
rem Select a random file
set /a "n=(%random% %% nFiles) + 1"
echo Selected file = %n% / %nFiles%
rem Count up to the selected file and start it
2>nul (
for /r "%~f1." %%a in ("%fileMask%") do (
set /a "n-=1", "1/n" || ( start "" "%%~fa" & goto :done )
)
)
:done
That is, count the number of files, select one of them and then start iterating over the list of files decrementing the number of the selected file. When it is 0 (we have reached the selected file), the 1/n division will fail and the conditional execution operator will execute the start command.
I'd try
) do start "" "%%~sB"
in the :openRandomFile procedure, which should open the file using its short name.
Sorry - can't test it as I don't have any UTF-8 filenames (that I know about)

Find multiple files' paths with the same file name

I tried to write a batch script that find all the paths of files that have the same name as the input string. right now it can find only the first file found, and i cant think of a way to make it list multiple files locations. I am not very experienced and I need some help.
this is part of the script code:
:start
cls
echo Enter file name with extension:
set /p filename=
echo Searching...
for %%a in (C D E F G H U W) do (
for /f "tokens=*" %%b in ('dir /s /b "%%a:\%filename%"') do (
set file=%%~nxb
set folderpath=%%~dpb\
::the path of the file without the filename included "C:\folder\folder\"
set fullpath=%%b
::the path of the file with the filename included "C:\folder\folder\file"
goto break
)
)
:notfound
cls
echo Enter file name with extension:
echo %filename%
echo File Not Found!
ping localhost -n 4 >nul
goto start
:break
if "%folderpath:~-1%"=="\" set folderpath=%folderpath:~,-1%
cls
echo ? %filename% found
echo %fullpath1%
echo %fullpath2%
echo %fullpath3%
--- || ---
I want the script to search the computer and list every encountered files with the same name and I want to be able to put those files' paths into different variables.
For example, if readme.txt is the input, then I want the list of all the paths of all the files with that specific name (readme.txt) and I want to set variable for each path so I can use it after that.
example:
input:
readme.txt
output:
3 files found
C:\folder\folder\readme.txt
C:\folder\folder\folder\readme.txt
D:\folder\readme.txt
variables:
path1 = C:\folder\folder\readme.txt
path2 = C:\folder\folder\folder\readme.txt
path3 = D:\folder\readme.txt
Here is a single script which will performs the task requested. It searches all drives for your input filename with extension, puts each found full file path into a variable, then output those variables for you. I will not be tailoring the script for any new changes after this response, advising on how to integrate it into the rest of your script or supporting any changes you may subsequently make.
#Echo Off
Set/P "SearchTerm=Enter file name with extension: "
Set "i=0"
For /F "Skip=1" %%A In ('WMIC LogicalDisk Where^
"DriveType>1 And DriveType!=5 And FreeSpace Is Not Null" Get DeviceID'
) Do For %%B In (%%A) Do (For /F "Delims=" %%C In (
'Where/F /R %%B\ "%SearchTerm%"2^>Nul') Do (Set/A i+=1
Call Set FullPath[%%i%%]=%%C))
If %i% LSS 1 (Echo= %SearchTerm% Not Found) Else (
Echo= %SearchTerm% had %i% match(es^)
For /L %%A In (1,1,%i%) Do (
Call Echo= %%%%FullPath[%%A]%%%% = %%FullPath[%%A]%%))
Timeout -1 1>Nul
Please be warned that searching many locations and putting many files into variables may over burden your system and cause issues.

Batch count all files but exclude those in a specific folder

So I'm going to count files in a directory including all subfolders and get a output as a number of how many files it found within the directory. The problem is I want to exclude all the folders that has the name error. Those files within that folder I do not want to be counted.
Simply...
for /r "\\server\share\folderA" %%G in (*.*) do (
set /A count=count + 1
)
echo %count%
Under folderA there are plenty of subfolders that I'm counting, but also the "error" folders that I do not want to count.
So I'm trying the following...
Create a temp file called exclude.txt and type error to that file
if not exist "c:\temp" mkdir "c:\temp" 2>nul
if not exist c:\temp\exclude mkdir c:\temp\exclude 2>nul
echo error> %excludefolder%\exclude.txt
Now I want to combine this somehow. Basically do something like this...
for /r "\\server\share\folderA" %%G in (*.*) EXCLUDE: c:\temp\exclude\exclude.txt do (
set /A count=count + 1
)
But I'm aware this will not work and I'm not sure how to work it out. Does anyone know? Thanks!
Use DIR /S /B /A-D to iterate all files. The output includes the full path to each file.
Pipe that result to FINDSTR /L /I /V "\\error\\ to filter out paths that contain \error\. This will also exclude any folders within an error folder. The search could be modified to exclude only 'error' but include children of 'error'.
Pipe that result to FIND /C /V "" to count the number of files (lines).
dir /s /b /a-d | findstr /liv "\\error\\" | find /c /v ""
The above will simply display the count.
If you want to capture the count in a variable, then use FOR /F to parse the output of the above command. Unquoted poison characters like | must be escaped when used in FOR /F.
#echo off
for /f %%N in ('dir /s /b /a-d^|findstr /liv "\\error\\"^|find /c /v ""') do set count=%%N
echo count=%count%
You can exclude from count the folder containing the string "error" :
#echo off
set count=0
for /r "\\server\share\folderA" %%a in (*.*) do (
echo %%~pa | find /i "error" || set /A count+=1
)
echo %count%
It's a good way if you sure that you just have ONE Error folder. If you have another folder containing the string "error" it will be excluded too from count.

Resources