How to count findstr results - cmd

I use 'findstr' to find certain common values in a lot of files and I get a list of all files containing it. Is there a way to count those results so I don't have to do it manually, or like enable row numbers in CMD?

I would typically do something like:
c:\>findstr some-string file.txt > results.txt
This will pipe the command line output into a new text file named results.txt
Go to Windows Explorer.   Find results.txt file.
Right-click --> Edit
Ctrl-A to select all
Look at very bottom of Notepad to see the total number of lines.

I use 'findstr' to find certain common values in a lot of files and I get a list of all files containing it.
So you probably use something like findstr /m "searchstring" *.*
Is there a way to count those results so I don't have to do it manually
yes, feed it through find, which can count:
findstr /m "searchstring" *.* | find /c /v ""
or like enable row numbers in CMD?
just for academic reasons (you already have your number):
findstr /m "searchstring" *.* | find /n /v ""
Just in case you need it as variable: use a for /f loop to catch the result:
for /f %a in ('findstr /m "searchstring" *.* ^| find /c /v ""') do set count=%a
(%a is command line syntax. Use %%a in a batch file)
Just in case Compo is right: to get the occurrences of the searchstring per file:
find /c "searchstring" *.* 2>nul
(2>0 suppresses errormessages for folders (which find tries to search, but miserably fails because they are not files [well, technically they are, but that's out of scope for your problem]))

Related

How to use findstr for multiple strings?

Can someone please help me with this. Is it possible to use findstr in order to find file names that contain 2 different strings, for example.
I have a folder called New Folder with 3 files called file1, file2 and file3.
file1 contains words one, two, three, four, five
file2 contains words one, three, four, five
file3 contains words two, three, four, five
How do I find the file which contains both "one" and "two", in this case file1. Is this possible to do with findstr or do I have to use grep (which I would like to avoid).
I tried running this command with CMD running in the current directory but I get blank result: findstr /s /m /c:"one" *.* | findstr /s /m /c:"two"
I also tried: for /f %a in ('findstr /s /m "one" "New Folder\*.*"') do #findstr /m "two" %a but I still get the blank result.
I do not want this as a .bat file but only as CMD command.
Please let me know if this is possible.
findstr /s /m /c:"one" *.* | findstr /s /m /c:"two"
for /f %a in ('findstr /s /m "one" "New Folder\*.*"') do #findstr /m "two"

When I put a batch program in the task scheduler, it didn't finish the whole task, so why did this happen?

This problem is from the scheduler task, batch program, or the files in a folder that I want to delete it using the batch program?
and this is the batch program:
forfiles /p "D:\nameOfFolder" /s /m *.* /d -7 /c "cmd /c del #path"
Replace /M *.* by /M * to even include files without extension, because forfiles treats wildcards differently than most other commands. /M * may even be omitted since this is the default setting anyway.
Regard that forfiles iterates both files and directories, so you need to exclude the latter, because del may try to delete its contents then. Therefore, implement a condition based on the forfiles-specific variable #isdir.
forfiles /S /P "D:\nameOfFolder" /M * /D -7 /C "cmd /D /C if #isdir==FALSE del #path"
As a side note, never append a trailing backslash to a (quoted) path, because something like /P "D:\" would let the command fail since \" constitutes an escaped quotation mark for forfiles, ruining the command line. You may however specify /P "D:\.".
Are you sure you even have such files?
I tried the following (very similar) command:
forfiles /p "C:\Temp_Folder" /s /m . /d -7 /c "cmd /c echo #path"
ERROR: No files found with the specified search criteria.
One thing I noticed, is that the name of the directory should not end with a backslash:
forfiles /p "C:\Temp_Folder" is working fine.
forfiles /p "C:\Temp_Folder\" is not working.
. on its own is not a valid searchmask to supply to /m.
You ned to use *.* (all) *.ext (the supplied extension) *string*.* (files with names containing the string).
? is also supported as a searchmask to match any character. example: *.?a* would match any file with an extension type with a as the second character

Windows command line - Remove files with specific extension, but not ones where extension contains substring (doc not docx)

I'm using wordconv.exe to convert a bunch of a old doc files into docx. Afterwards I'd like to delete the original doc files.
When I run "del /S *.doc" on the command line it deletes both the doc and docx files. Anyway to get it to delete just .doc files?
Thanks!
Let's try to use something like this:
forfiles /s /m *.doc /c "cmd /c del #file"
The problem is the short 8.3 names of the files, because for internal cmd commands and also many external ones, wild-cards (*, ?) also match against them. For example, a file like important-document.docx has got a short name like import~1.doc, which is matched by *.doc.
There are some commands that treat wild-cards differently:
forfiles (as already demonstrated in the answer by Michał Mielczarek):
forfiles /S /M "*.doc" /C "cmd /C if #isdir==FALSE del #relpath"
The #isdir query checks whether the current item is a file and lets skip folders.
where:
for /F "delims=" %%F in ('set "PATHEXT=" ^& where /R "." "*.doc"') do #del "%%~F"
The surrounding for /F loop captures the result of where. The command set "PATHEXT=" deletes the PATHEXT variable in the cmd instance in which where is executed, because this also regards that variable, so a file like important-document.doc.com could also be matched unintentionally with a default value of PATHEXT of .COM;.EXE;.BAT;.CMD, for instance.
Although the where approach appears a little bit more complicated, you might prefer it, because it is faster than forfiles, particularly when having a huge directory tree.
N. B.:
forfiles /M "*.*" does not match files (or folders) with no extension (so use /M "*" to match something like testfile), but where "*.*" does, so this indicates that these two commands have their own individual wild-card handling/substitution routines.
for /f "tokens=*" %%? in ('dir /b /a-d /s *.doc') do if /i "%%~x?"==".doc" del "%%~f?"
You can add if exist "%%~dpn?.docx" before del, if .doc and .docx are in same folder.

Command line to list files with timestamps, sizes, and paths

I have the following command line that extracts the timestamp, size, and file name of specific files, however I need the entire path listed. What should I use for this task?
DIR "C:\Users\Heather\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\" "*Process*" /S /A:-D /TW /OSD
Assuming you are looking for files matching the pattern *Process* within the directory C:\Users\Heather\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\, you could use the following code:
forfiles /S /P "C:\Users\Heather\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5" /M "*Process*" /C "cmd /C if #isdir==FALSE echo #fdate #ftime #fsize #path"
The great advantage of the forfiles command is that the time stamp is returned with a resolution of 1 second (rather than 1 minute as with dir or for).
However, the sort order you used in your dir command line (/O:SD) is not maintained.
for /f "delims=" %a in ('DIR "C:\Users\heather\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\" "*Process*" /S/b /A:-D') do #echo %~za %~da %~ta %~fa
should provide that data.
Note that you appear to be looking for all files in "C:\Users\heather\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\" and also for "Process"

Exclude specific file extension

Alright, I'm new to scripting and I'm trying to edit a batch script file that sends an email when a file with an extension of .ecl is in a folder longer than 5 min or so. But there are other files with a .ecl.part extension that get flagged and it sends an email instead of the .ecl files. I'm curious if there is something I can add so that it will send an email when there are .ecl files in the folder for more than 5 min and ignore the .ecl.part files. I read one for someone with Linux who used [!(.extension to exclude)].extension not to exclude, I'm just wondering if this will work for my windows batch script. If it will work do I add it just like that or do I add it like this .extension not to exclude[!(.extension to exclude)]
Here is the part of the script in question:
for /f "tokens=1-5 delims=:, " %%a in ('forfiles /p z: /d +0 /s /m *.ecl /c "cmd /c if #isdir==FALSE echo #file,#ftime"') do (
set fnam=%%a
set fhr=%%b
set fmin=%%c
set fsec=%%d
set fampm=%%e
if "!fampm!" == "PM" if "!fhr!" neq "12" (set /a "fhr=!fhr!+12")
There is more of the script, I didn't set this up, and the person who did isn't being very helpful which is why I came here.
#ECHO OFF
SETLOCAL
SET savearea=c:\destdir
SET emldir=c:\sourcedir
ECHO.>"%savearea%\emlfiles.new"
DIR /b /a-d /on "%emldir%\*.eml" >>"%savearea%\emlfiles.new"
IF NOT EXIST "%savearea%\emlfiles.old" GOTO noold
FOR /f "usebackqdelims=" %%i IN ("%savearea%\emlfiles.new") DO (
FINDSTR /b /e "%%i" "%savearea%\emlfiles.old" >NUL
IF NOT ERRORLEVEL 1 (ECHO %%i is MORE than 5 minutes old)
)
:noold
MOVE /y "%savearea%\emlfiles.new" "%savearea%\emlfiles.old" >nul
GOTO :eof
This script saves in %savearea% a sorted basic filelist of the *.eml files in %emldir% then compares the new list to the previous version. If the same filename appears in both, it will generate the message %%i is MORE than 5 minutes old
So - all you need to do is point emldir to wherever your .eml files reside, savearea to some safe directory, replace the message ECHOing with an email-sending command of your liking and schedule it to run each 5 minutes using task scheduler.
Although in my testing I find this not to be the case, it sounds like forfilesis evaluating wildcards against 8.3 short filenames on your computer. You know how if you're in a directory containing both .doc and .docx files and you do a dir *.doc, the .docx files will be listed as well? Same sort of thing.
So *.ecl is matching your .ecl.part files because in 8.3 notation they've got a .ecl extension. You could either make sure %fnam:~-4%==.ecl, enclosing most of the guts of your for loop within an if statement; or you can use find or findstr to filter the output of forfiles as captured by the for loop. Something like this:
for /f "tokens=1-5 delims=:, " %%a in (
'forfiles /p z: /d +0 /s /m *.ecl /c "cmd /c if #isdir==FALSE echo #file,#ftime" ^| find /v /i ".part"'
) do (
set fnam=%%a
set fhr=%%b
set fmin=%%c
set fsec=%%d
set fampm=%%e
if "!fampm!" == "PM" if "!fhr!" neq "12" (set /a "fhr=!fhr!+12")
rem etc.
Since find /v prints lines not matching its search, that should effectively filter out the .ecl.part files. find /v works like grep -v in Linux.
You know, since my test cases don't seem to match the symptom you're describing, I am very curious to know whether simply replacing if #isdir==FALSE with if #ext==\"ecl\" would also prevent the .ecl.part files from being included. But if you don't feel like experimenting to satisfy my curiosity, I totally understand.

Resources