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 = []
Related
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.
I have several files like:
a.txt
a$.txt
a$b.txt
b.txt
b$.txt
b$c.txt
I would like to print file whose name does not contain '$' using Windows command line for file name pattern matching like regular expression:
for %%f in ([^$]+.txt) do type %%f
or
for %%f in ([a-zA-Z]+.txt) do type %%f
But it does not work. How can I do this using Windows command line? Thanks!
The for loop, like almost all cmd commands, does not support something like regular expressions. The only command that supports a tiny excerpt of those is findstr, which can be used together with dir to get the desired result:
#echo off
for /F "delims= eol=|" %%f in ('
dir /B /A:-D "*.txt" ^| findstr "^[^$][^$]*\.txt$"
') do (
>&2 echo/%%f
type "%%f"
)
This could even be simplified by replacing the portion findstr "^[^$][^$]*\.txt$" with find/V "$".
As 'Windows command line' includes powershell.exe as well as cmd.exe, I thought I'd offer a powershell based idea too.
Directly in powershell:
Get-Content -Path 'C:\Users\Xiagao\Desktop\*.txt' -Exclude '*$*.txt'
In cmd/batch-file, but leveraging powershell:
PowerShell -NoP "GC 'C:\Users\Xiagao\Desktop\*.txt' -Ex '*$*.txt'"
You would obviously modify the path to your source files location, (use .\*.txt for the current directory).
From Windows CMD I can use
findstr -m subroutine *.f90
to list all files with suffix .f90 containing "subroutine". To list all .f90 files not containing the string I can do something like
dir /b *.f90 > files.txt
findstr -m subroutine *.f90 > files_with_string.txt
and then write a script to list the lines in files.txt not found in files_with_string.txt. Is there a more elegant way?
There is a /v option in findstr, but that wouldn't help here.
Process each file with a for loop, try to find the string and if it doesn't find it (||), echo the filename:
for %a in (*.f90) do #findstr "subroutine" "%a" >nul || echo %a
(above is command line syntax. For use in a batchfile, use %%a instead of %a (all three occurences))
I needed to search for filenames which contained one specific string ("up"), but did not contain another string ("packages").
However, I was hoping to run it from the command line.
This is actually possible to do, you just have to call findstr twice.
Mine looked like:
dir /B /S up | findstr /I "up" | findstr /I /v "packages"
That means:
search all directories (/S & subdirs)
give me the bare formatting (/B)
and pass it through (| pipe) findstr (/I ignore case) to find ones that have "up" then
pass the results (| pipe) through findstr again but this time ignore all that
contain (/v) "packages"
If you have items like:
c:\test\packages\up
c:\extra\thing\up
c:\extra\thing\packages\up
c:\extra\test\up
c:\extra\test\nothing
The results would be only the ones that contain "up" but do not contain "packages"
c:\extra\thing\up
c:\extra\test\up
Call findstr /v multiple times on result
In other words you can keep passing the result into another findstr with /v to remove the ones that have additional words you don't want.
I'd like to be able to search files on a Windows machine using the command line instead of the GUI interface. For example, on Linux, I use:
find . -name "*.c" -exec grep -Hn "sqlcommand" {} \;
Is there something similar with Windows?
After long time working with Unix systems I had to make some scripts on Windows.
For serious scripting Powershell is the tool you should use.
You can search Internet with keywords like powershell find string in file,
or other combinations and you find a lot of information.
That's the problem, a simple oneliner like
get-childitem C:\yourdir -include *.c -recursive |Select-String -pattern sqlcommand
won't help you much. You need to find the PowerShell IDE, learn the different syntax and try to love / accept that new stuff.
Prepare for a study with PowerShell when you want to do these things more often, or try to get a Unix-like environment on your windows (cygwin, or better git for windows)
NEW AND IMPROVED ANSWER
I recently stumbled upon a built-in command that is rather similar to find in Unix:
ForFiles
Basic syntax is:
forfiles [/p <Path>] [/m <SearchMask>] [/s] [/c <Command>] [/d [{+|-}][{<Date>|<Days>}]]
There are several variables to use when constructing the command to execute per each file (via the /c switch):
#FILE File name.
#FNAME File name without extension.
#EXT File name extension.
#PATH Full path of the file.
#RELPATH Relative path of the file.
#ISDIR Evaluates to TRUE if a file type is a directory. Otherwise, this variable evaluates to FALSE.
#FSIZE File size, in bytes.
#FDATE Last modified date stamp on the file.
#FTIME Last modified time stamp on the file.
It looks like you would use the command like this:
FORFILES /m *.cs /c FINDSTR /I /N /C:"sqlcommand" #FILE
I'm not sure how long this command has been around, but the earliest reference I could find in the documentation is from 2008-09-02:
https://web.archive.org/web/20080902221744/http://technet.microsoft.com:80/en-us/library/cc753551.aspx
and that page states that it was last updated on "April 25, 2007". The documentation is filed under "Windows Server" so it likely started there and was added to the desktop OSes starting with Windows Vista, I believe. I did check Windows XP and didn't see it there, though it is on Windows 10.
ORIGINAL ANSWER
This requires a combination of two DOS commands:
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
and
DIR /B /O:N /W *.c (this is the 'command' noted in the FOR command above)
Create a CMD script as follows:
#ECHO OFF
FOR /F %%B IN ('DIR /B /O:N /W *.cs') DO (
findstr /I /N /C:"sqlcommand" %%B
)
OR, just use the find command found in this set of Unix command ports:
http://unxutils.sourceforge.net/
or
http://sourceforge.net/projects/unxutils/
(both links should be the same project)
I need to find the files in a directory that have specific strings, using Windows CMD prompt.
E.g., I need to find the files that have a string like this:
<h1>Select an Item</h1>
"findstr" iswhat you are looking for.
findstr /I "<h1>Select\ an\ Item</h1>" *.*
findstr is the command, /I is a flag to match the string case insensitive. "<h1>Select\ an\ Item</h1>" is your string (note the escaped spaces!) and *.* means "in all files in this directory".
The basic syntax is findstr "seachString" filename.ext.
You may replace filename.ext with *.ext or *.* to filter cretin file types or look in all files.
This will look only in the current directory and not recursively.
More information about the command findstr documentation
The command you require is fundamentally findstr.
type
findstr /?
at the prompt for directions.
The command that may work for you is
findstr /m /g:"a file containing your string or strings" *
or
findstr /m /L /c:"<h1>Select an Item</h1>" *
Where some experimentation with the contents of the "quoted string" may be required, especially wrt characters line <>() and others with a particular meaning to cmd.exe.
Find some string inside all text files in current directory:
cls & for %i in (*.txt) do find /i "search text" < "%i" && (echo : %i & echo -)
Tested in Win 10