Find specific text in files - windows

Simple as the title says... I thought I could use these commands because of what the find command says on its help but it is not working for me. Am I missing anything?
dir /s /f *.txt | find "READONLY"
With that I want to find every occurrence of the word "READONLY" in every .txt file.
Edit: While writing this question I looked for the suggestions and the findstr command showed up. But it is not finding anything at all.

I'm not sure what you are trying to do.
The /F option is not valid for the DIR command. Correction - I'm told the /F option is a Windows 8 feature. Ignoring that problem, your command is attempting to look for the string READONLY in the output of the DIR command. That will never happen unless a folder or file name contains the text "READONLY" in the name.
If you want to list files that contain "READONLY" in the file content, then:
findstr /s /m READONLY *.txt
The above is case sensitive. If you want case insensitive, then add the /I option.
findstr /s /m /i READONLY *.txt
If you want to list files that have the READONLY attribute, (you cannot modify them), then
dir /s /ar *.txt

find every occurrence of the word "READONLY" in every .txt file [recursively starting from the current directory]
for /f "tokens=1 delims=" %f in ('dir/s/b *.txt') do findstr "READONLY" %f
Be sure to replace % with %% if you're running within a script.

Try using
grep -R 'READONLY' *.txt

Related

Windows cmd: piping the dir list output into find (or findstr) is not working

I need to do some very big Windows searches for some specific searchterms in th contents of all the files in a folder and all sub-folders. The GUI search facility is not finding all my tests, so I would like to try to use find via the cmd.
I can list all filenames in raw data format using:-
dir /S /B
I can successfully search for the searchterm in thecontents of all files in a single folder using :-
find "Searchterm" *.*
But there are thousands of recursive sub-folders, so when I pipe the output from the dir listing to the find (and exclude the filename parameter):
dir /S /B | find "Searchterm"
I am getting no results.
Furthermore, I have also successfully sent all the dir /B /S filenames to a text file:-
dir /S /B >> filenames.txt
and using type to pipe the contents of each file from the list to the find :-
type filenames.txt | find "Searchstring"
This does not work either. What am I missing? Microsoft's documentation suggests exactly the same format in https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/find as I am trying.
The solution to your question(s) should be clear by reading the output from %SystemRoot%\System32\findstr.exe /? ENTERed in a Command Prompt window.
I'd advise that you use the /L, literal, option for your initial code.
Direct results example:
%SystemRoot%\System32\findstr.exe /I /L /P /S "Searchstring" *
If you first send the filenames to a text file, e.g. Dir /B /S /A:-D 2>NUL 1>"filenames.txt", you could use the following idea:
%SystemRoot%\System32\findstr.exe /F:"filenames.txt" /I /L /P "Searchstring"
Just be aware, in this case, that unless you include a path outside of the target tree when initially creating filenames.txt, it will include itself in its own content. That means your FindStr command will also pick up any matches in that file too.

Extract line of text from .txt file using CMD?

was wandering if there is a way to extract a line of text which contains certain value from a .txt file using CMD. For example using "type filepath\example.txt" will open the whole file and in my case I am working trough a software which doesn't allow CTRL+F option and .txt files are massive.
Is there any way I could specify certain word in order to get that whole line of text or to open only .txt files which have that word within them. For example I have 1000 .txt files and all of them contain the same text but only one of them has a word "EXAMPLE" in it. Could I use some command to find and open that file using CMD.
Thank you.
I have 1000 .txt files and all of them contain the same text but only one of them has a word "EXAMPLE" in it. Could I use some command to find and open that file using CMD.
a) find the file(s) that have the desired string:
findstr /m "EXAMPLE" *.txt
b) find the file (assuming, only one contains the string; else it will open all matching files) and open the file in notepad:
for /f "delims=" %a in ('findstr /m "EXAMPLE" *.txt') do "%a"
c) find the one line that has the string:
findstr "EXAMPLE" *.txt
The findstr.exe solution from Stephen would be less typing. But, using Select-String allows the use of a much more complete implementation of regex. All supported Windows systems have PowerShell available. This works in a batch-file run by cmd on windows and at the command prompt. Given that this would likely be put into a batch-file, the amount of typing is not very significant.
#powershell.exe -NoLogo -NoProfile -Command ^
Get-ChildItem -Path '.\*.txt' ^| ^
ForEach-Object { Select-String -Pattern 'example' -Path $_ } ^| ^
Select-Object -Property Filename,Line
Not the most elegant alternative, I agree, and I am certain someone will tell me how it could be bettered. The key is it uses basic find a string (you can set as I have to be case insensitive) in a file then reports filename and line number, Line [9] in this case.
#forfiles /m *.txt /C "cmd /c (find /n /i \"For example\" "#file"1>nul) &&if %errorlevel%==0 (find /n /i \"For example\" "#file"2>nul)"
When used in a batch file it could look something like this, but see caveats below
Finder$.cmd
#echo off & Title Find wally String in a file
set "string=where's Wally"
if not "%1"=="" set "string=%~*"
forfiles /m *.txt /C "cmd /c (find /n /i \"%string%\" "#file"1>nul) &&if %errorlevel%==0 (find /n /i \"%string%\" "#file")"
echo/ & pause & exit /b
It is not perfect but note its not case sensitive (using /i), it can readily fail if *.txt files are not plain text and as written will only accept a short unquoted string of up to 9 words ( avoid " or other punctuation). It works in local directory with *.txt, but you could alter those as require to first say cd /d f:\mylogs and search *.log files.
Finally you asked to open the file thus we can simplify for that task to call an editor like notepad or with some fetteling one that accepts line numbers (but that is another question)
forfiles /m *.txt /C "cmd /c (find /n /i \"%string%\" "#file"1>nul) &&if %errorlevel%==0 (notepad.exe "#file")"
Everything below is related to unix bash terminal, so please install Linux Subsystems if you are using Windows. Or even Linux itself :)
You can open specific file in a text editor like Vim or Nano in terminal. They offer the "CTRL+F" function.
Below you can see me searching for the "gameId" keyword in the file game_stats.js, which I opened via $ vim game_stats.js.
P.S. To quite vim you need to type :q :)
Use grep command as advised in this answer https://stackoverflow.com/a/16957078/13212398
Example for the command that recursively searches for any .js or .txt files that contains "let" in the current directory (.).
$ grep --include=\*.{js,txt} -rnw -e "let" .
./this_test.js:18:let bob = new Person('Bob');
./this_test.js:19:let bill = new Person('Bill', bob);
./TUD-2Q-WDB/checkers-in-delft/public/javascripts/game_state.js:99: let pieces = []

How to show only filenames without extensions using dir command

I'm trying to list out file names excluding their extension,
How I want it:
File1
File2
File3
How it currently is:
File1.txt
File2.txt
File3.txt
I tried using
#echo off
dir /A:-D /B
pause
but it isn't working. I tried it in both a batch file and in command prompt.
Am I using the right command?
Use FOR and ECHO to achieve this
For example, assuming the extension is always .txt:
for %f in ("*.txt") do #echo %~nf
Instead of using DIR, we are using the FOR command to go through the list and sending each one to ECHO, with the "~n" option inserted into the %f, to cause the extension to be not shown.
An alternative is
FORFILES /c "cmd /c echo #fname"
However with this I get quotation marks around each output filename, which isn't what you want.
If running inside a batch file, you need to double the %'s for variables
for %%f in ("*.txt") do #echo %%~nf
If you need to handle multiple file extensions
As long the directory doesn't contain any subdirectories whose names have an extension, you can generalise the *.txt to *.*:
for %f in ("*.*") do #echo %~nf
If you may have some filenames with only an extension
Where the file has an extension but nothing before it, e.g. .gitignore, the resulting empty ECHO command will output an inane message, such as ECHO is on. To avoid this ruining your onward plans, you can filter out lines containing ECHO is, with the FIND command and the /V option:
for %f in ("*.*") do #echo %~nf | find /v "ECHO is"
If your local language causes DOS to output something other than ECHO is then this filtering will not work. And it will miss any file that happens to contain ECHO is in the filename.
To search subdirectories too, add '/R' to the 'for'
for /R %f in ("*.png") do #echo %~nf | find /v "ECHO is"
Conclusion
This is all crazy, of course, but this is the agonising price we pay for using Batch language instead of an actual sensible language. I am like an alcoholic, promising to all and sundry that I will never write a line of Batch code again, and then finding myself coming back to do so again, sheepishly.
It'll be much easier in PowerShell
(Get-ChildItem -File).BaseName
or
Get-ChildItem | ForEach-Object { $_.BaseName }
Get-ChildItem can be replaced with the aliases ls, gci or dir and ForEach-Object can be replaced with %
So from cmd you can run either of these to achieve the purpose
powershell -Com "(ls -File).BaseName"
powershell -C (ls^ -File).BaseName
powershell (ls^ -af).BaseName
To add to Eureka's answer, the vanilla dir command cannot achieve what you're looking for.
C:\Users\jacob>dir /?
Displays a list of files and subdirectories in a directory.
DIR [drive:][path][filename] [/A[[:]attributes]] [/B] [/C] [/D] [/L] [/N]
[/O[[:]sortorder]] [/P] [/Q] [/R] [/S] [/T[[:]timefield]] [/W] [/X] [/4]
[drive:][path][filename]
Specifies drive, directory, and/or files to list.
/A Displays files with specified attributes.
attributes D Directories R Read-only files
H Hidden files A Files ready for archiving
S System files I Not content indexed files
L Reparse Points - Prefix meaning not
/B Uses bare format (no heading information or summary).
/C Display the thousand separator in file sizes. This is the
default. Use /-C to disable display of separator.
/D Same as wide but files are list sorted by column.
/L Uses lowercase.
/N New long list format where filenames are on the far right.
/O List by files in sorted order.
sortorder N By name (alphabetic) S By size (smallest first)
E By extension (alphabetic) D By date/time (oldest first)
G Group directories first - Prefix to reverse order
/P Pauses after each screenful of information.
/Q Display the owner of the file.
/R Display alternate data streams of the file.
/S Displays files in specified directory and all subdirectories.
/T Controls which time field displayed or used for sorting
timefield C Creation
A Last Access
W Last Written
/W Uses wide list format.
/X This displays the short names generated for non-8dot3 file
names. The format is that of /N with the short name inserted
before the long name. If no short name is present, blanks are
displayed in its place.
/4 Displays four-digit years
Switches may be preset in the DIRCMD environment variable. Override
preset switches by prefixing any switch with - (hyphen)--for example, /-W.
Additionally, as an alternative to the suggestion to use ("*.txt"), if your file list includes multiple extensions you might either exclude different extensions or use *.* to get all files with a . in the name. Play around with that glob to get what you want out of it.
This is possible with a dir command and a for loop:
#echo off
for /F "delims= eol=" %%A IN ('dir /A-D /B') do echo %%~nA
If you want the full path without the extension, try:
#echo off
for /F "delims= eol=" %%A IN ('dir /A-D /B') do echo %%~dpnA
For cmd one-line:
for /F "delims= eol=" %A IN ('dir /A-D /B') do echo %~nA
And for the full path without the extension, try:
for /F "delims= eol=" %A IN ('dir /A-D /B') do echo %~dpnA
These small programs, loop through all the files in the folder except directories, and echo only the filenames/full paths without the extension.
dir -Name -File
This is for PowerShell

Batch file giving File Not Found error

Been working on a systematic file search script to retrieve the name of all documents in a directory, and all sub directories that contain a determined search string. Essentially, it will log the search results. It would be nice to have it also search the file names, but that's not yet important.
Code:
#echo off
echo - Will search all files in current directory, and subdirectories.
echo - Will ignore case sensitivity.
echo - Will only search for term within readable documents.
set /p searchfilter=Search Filter:
set results=%CD%\results.txt
echo Searching...
echo Results: > "%results%"
for /f "usebackq tokens=*" %%i in (`dir /s/b/A:-D/o:e`) do (
find /i "%searchfilter%" "%%~nxi" >nul && echo %%~nxi >> "%results%"
)
echo Search complete.
pause
Run-down: System requests a string from the user. Then, the system saves a handle to the results file (thought that would fix the problem, didn't). The system then filters all files, excluding folders, from the directory, and sub directories, printing the bare name of the file (with extension), where it will proceed to scan each file for the search string, and save any positive search results to the text file.
It seems on a number of files, I receive a "File not found - " error, and need help identifying it. My guess, is that it has something to do with trying to find a sub directory file without the directory handle.
find /i "%searchfilter%" "%%i" >nul && echo %%~nxi >> "%results%"
should fix your problem, as you've flagged yourself. If you are searching for a file named fred.txt that exists in a subdirectory but mot in the root of the subtree scanned, then you'll get a File not found error.
Your choice whether you echo just the name and extension to results or whether you echo the full filename, of course. Personally, I'd use `%%i and get the whole thing.
I'd also change
for /f "usebackq tokens=*" %%i in (`dir /s/b/A:-D/o:e`) do (
to
for /f "delims=" %%i in ('dir /s/b/A:-D/o:e') do (
but that's just a matter of style in this case.
This should give you a tool to search filenames in the current folder tree and log the results to a file - in c:\path\file.ext format.
Replace searchstring with your search term and remove *.doc if you want to search all files, or replace it with *.doc *.txt *.ini *.src if you want to filter a number of filetypes.
#echo off
dir /b /s /a-d *.doc |findstr /r /i ".*\\.*searchstring.*" >results.txt

How do I find a directory in and store it into a variable, using a Windows batch file?

I need to find the location of a specific directory, and then store that directory path into a variable within a Windows batch script.
I also want the command to return when it finds a match (to avoid searching the entire hard drive once the directory has already been found).
So far I've tried this on the command line:
dir c:\ /s /b /ad | find "DirectoryName"
The problem with this is that it searches the entire drive, even after a match is found. Plus, I still can't figure out how to store the result in a variable within a batch file. There should only be a single result.
Basically I need the equivilent of somehting like this on Linux/bash:
export DIRPATH=`find / -name "DirectoryName" -print -quit`
Thanks for looking!
In batch you need FOR /F to get the output of a command.
FOR /F "usebackq delims=" %%p IN (`dir c:\ /s /b /ad ^| find "DirectoryName"`) DO (
set "DIRPATH=%%p"
)
echo %DIRPATH%
As there are quotes in the find command you need the usebackq-option.
And it's necessary to escape the pipe character one time, as it should pipe the dir command, not the for command

Resources