Batch file findstr with spaces and blank lines - batch-file

I have a batch script below which reads strings with spaces, line by line from a reference text file(testException.txt). I am using findstr to search in my text.txt to find any match to the strings in the reference file. If there is any match, i want to output everything in the text.txt to an error textfile and exit the loop.
:find.bat
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set source=testException.txt
set location=text.txt
for /f "tokens=* delims=" %%L IN (!source!) DO (
#findstr /B /I /C:"%%L" "!location!"
if %ERRORLEVEL% EQU 0 (type !location! >> Error.txt goto:eof) else (call)
)
pause
When I execute my script, it outputs as many times as the number of patterns in my testException.txt. It seems like my goto:eof does not end my for loop. Below is my text.txt and testException.txt. Any help & suggestions for a better way is greatly appreciated.
text.txt
hello, how are u.
im fine ty.
lol. apple 123 is here
testException.txt
orange 321
apple 123
lol 423

Related

Batch print line until string found

I have a batch script that generates a file with the following structure (example)
123|etc|etc
345|etc|etc
678|etc|etc
I want my script to print out what it finds in each line, until it finds a |, so in this example i would want it to print:
123
345
678, and so on.
I've tried findstr /V with the | but it completely ignores the line (as the command states it will)
Any idea how could i turn this around?
#echo off
for /f "usebackq tokens=1 delims=|" %%a in ("test.txt") do (
echo %%a )
pause
This is looping through a file (test.txt) in the same directory as the batch script. I tell it to only use 1 token with a pipe delimiter then we just print out %%a which has the value of your first column of data.

How to process each line a text file and do something with each line

How to process each line a text file using batch file, and check a string contains in the current line, do something if true else do something else and continue to next line until eol.
I have a text file containing lines like this:
\\.\DISPLAY2|ASPEED Graphics Family(WDDM)
\\.\DISPLAY7|NVIDIA Tesla M10
\\.\DISPLAY11|NVIDIA Tesla M10
\\.\DISPLAY15|NVIDIA Tesla M10
\\.\DISPLAY3|NVIDIA Tesla M10
\\.\DISPLAY10|ASPEED11 Graphics Family(WDDM)
I need to get the number next to the word 'DISPLAY' if that line contains the word 'NVIDIA'
So in this example, I should get the numbers 7, 11, 15 and 3
The easiest way to do this is to use a FOR statement to state each line of the text document as a string. Because of the format of your text document, we cant simply use tokens= alone to extract just the numbers.
Using findstr /i "NVIDIA" "list.txt" we can have the script only read lines that test positive for containing the word NVIDIA - Where list.txt is the name of your text file.
Using syntax-replace we can vary easily extract just the number by doing the following:
Removing everything before and including DISPLAY
Removing everything after and including the |
The number from each line will be set as the variable !string!.
For checking if the number exist true, you can use an IF statement inside your FOR statement. Example, If "!string!"=="Number" (). Please keep in mind that if attempt to use goto inside your FOR loop, it will break the loop and exit the loop (Thus not checking new lines).
#ECHO OFF
setlocal enabledelayedexpansion
for /f "tokens=1,2" %%G in ('findstr /i "NVIDIA" "list.txt"') do (
set string=%%G
SET string=!string:*DISPLAY=%!
SET endbit=!string:*^|=%!
call set string=%%string:!endbit!=%%
If "!string!"=="7" (
:: Do some code for 7
echo string equals 7!
)
If "!string!"=="11" (
:: Do some code for 11
echo string equals 11!
)
If "!string!"=="15" (
:: Do some code for 15
echo string equals 15!
)
If "!string!"=="3" (
:: Do some code for 3
echo string equals 3!
))
Please feel free to change the script to your need's.
It is not fully clear whether you're wanting to work on only those lines containing NVIDIA.
If you do, then based on your provided information, you can try this:
#Echo Off
For /F "Tokens=2 Delims=Yy|" %%A In (
'FindStr /I "DISPLAY[0-9]*|NVIDIA" "File.txt" 2^>Nul') Do Echo %%A
Pause
If you're wanting to work on all string content, but have only provided information on what you wish to do with those lines containing NVIDIA, this may help:
#Echo Off
For /F UseBackDelims^=^ EOL^= %%A In ("File.txt"
) Do Set /P "=%%A"<Nul|FindStr /I "DISPLAY[0-9]*|NVIDIA">Nul 2>&1 &&(
For /F "Tokens=2 Delims=Yy|" %%B In ("%%A") Do Echo %%B
)||Echo Do something else
Pause
The examples above use the text file name, File.txt, please adjust it as necessary.

Batch Script: Merge Content From .txt List to one file

On Windows 10 I have this .bat:
#echo off
for /f "delims=" %%i in (filelist.txt) do (
echo %%~nxi >> output.txt
type "%%~ni*" >> output.txt
echo. >> output.txt
echo. >> output.txt
)
Exit
Now what this does is:
reads filelist.txt, which contains names of .txt files like:
20180808173105 (without ".txt"
searches for those files: 20180808173105.txt
copies name of files (without ".txt") into output.txt
inserts content of files
inserts two blank lines
repeats whole process for all files named in filelist.txt
--> It works fine! (or do you see any exception where this might malfunction?)
This inserts the full contents of a text file according to a list.
Can I modify it, so
not the whole content of a .txt, but only a part of it is inserted?
For example, everything from just after "title:" to just before "<!--"
if the filelist had a hierarchical structure (outline), it could
be preserved, like so:
#201508081213
###201609101219
to
#201508081213
TEXT
###201609101219
TEXT
I am using this to convert Outlines (using only the file names) to a rough first draft of text for writing articles and blogs
#echo off
2> output.txt echo.
#>&3 (
echo Debug Information
echo -----------------
)
for /f "delims=" %%A in (filelist.txt) do (
for %%B in ("%%~nA*") do call :read "%%~B"
) >> output.txt
exit /b
:read
setlocal
set "line="
echo(%~nx1
for /f "usebackq delims=" %%C in ("%~1") do (
set "line=%%C"
for /f "tokens=*" %%D in ('call echo "%%line:~0,4%%"') do (
#>&3 echo File: "%~1" Test: %%D == "<!--"
if %%D == "<!--" (
#>&3 echo Found: "<!--"
echo.
echo.
exit /b 0
)
)
call echo(%%line%%
)
echo.
echo.
exit /b 0
Note
Not the best language for this task. Had to avoid
enabledelayedexpansion as to known use of ! in <!--.
Used call even though < and some other characters
could cause issue.
for /f loops do not normally process empty lines so
hope that is not a problem.
Hierarchical structure depends on the order in filelist.txt.
The structure of a document can vary and I cannot consider
what the correct order might be. The use of a wildcard gives
some doubt. A filename #a will find #a1 and #a2 so
placement of 3 headings is unknown.
I have left in the std stream 3 messages for your
understanding of operation with the <!-- test.
Std stream 1 is the output that goes to file.
Operation
The file output.txt is erased before echoing text to the file.
The 1st for loop reads each line of the filelist.txt file.
The nested for loop gets the filenames with a wildcard.
Each call to label :read passes the argument of a filename.
In the label of :read, the filename is echoed.
A for loop reads lines from the filename.
Each line is stored in variable named line.
The nested for loop will use call echo to expand
the variable line and echoes the 1st 4 characters.
A comparison is done to test if it is <!-- and if so,
echo 2 newlines and then the label is exited.
If not, echo each line. echo 2 newlines is done at
the end of the label before exiting.

Batch File FOR loop using variable

I extracted the last line of a text file using the following command:
for /f "tokens=*" %%m in (message_log.txt) do (
Set lastline=%%m
)
My goal is if the variable %lastline%=="☺§☻PDF file has been aborted.
then to display one output and if not exit. But I think the first three characters are messing it up. I am trying this:
for /F "tokens=1-5 delims= " %%a in (%lastline%) do (
if %%e==aborted. (
echo pdf not filed
)
Pause
but the file just exits, with no pause and no output.
I can get this to work if instead of using %lastline% I refer to a file as I did in the first for loop, however I cannot get it to work with a variable.
What is the correct syntax to use a FOR loop to search inside a predefined variable?
If it is simpler my ultimate goal is to echo an error message if the last line in my text file contains the string "abort". Is there a better way to do this?
Your first approach is OK, just missing the check.
for /f "delims=" %%m in (message_log.txt) do Set lastline=%%m
If "%lastline%" neq "%lastline:abort=%" ^
Echo error message the last line in message_log.txt contains the string "abort"
With findstr
for /f "delims=" %%m in (message_log.txt) do Set lastline=%%m
Echo %lastline%|Findstr /i "abort" 2>&1 >Nul && ^
Echo error message the last line in message_log.txt contains the string "abort"
With Gnuwin32 tools installed
tail -n 1 message_log.txt|grep "abort" >NUL && ^
Echo error message the last line in message_log.txt contains the string "abort"

Cannot echo in the same line in Batch script

I have txt files that contain several lines and I need to create a log out of them to store in a log the following information:
File Name
Last modified
Count of lines containing the word "valid"
I've put together a .bat file but it splits the output in two lines.
type nul > FilesReceived.txt & for %f in (*.log) do (
find /c "valid" %f & echo(%~tf)>> LogsReceived.txt
)
With type nul I clear the contents of the FilesReceived.txt file. Then I loop through the files of type log.
Then I count lines that contain the word valid with find /c and I also echo the last modified time stamp.
However the output looks like:
---------- transaction_20160505_1005A.log: 6492
10/06/2016 04:37 p.m.
I don't know what's generating those dashes. Ultimately I'd like to have one line per log file as follows:
transaction_20012B.log: 6492 10/06/2016 04:37 p.m.
Hope you guys can help me.
Thanks,
Bruce
find prints the dashes if it processes a file. It doesn't, when processing from STDIN (type file.ext /c |find "string" prints the count only).
There is a trick to write without linefeed: <nul set /p"=Hello"
If you can live with another order, it's quite easy to assemble it::
#echo off
for %%f in (*.bat) do (
<nul set /p "=%%f %%~tf "
type %%f|find /c "echo"
)
If you want to keep your order it's a little bit more complicated: you can't force find to write without linefeed, so you have to use a trick (another for):
#echo off
(for %%f in (*.txt) do (
<nul set /p "=%%f: "
for /f %%i in ('type %%f^|find /c "valid"') do (<nul set /p "=%%i ")
echo %%~tf
))>LogsReceived.txt
You may get the output of find command via another for and put it at any place you wish:
#echo off
(for %%f in (*.log) do (
for /F %%c in ('find /c "valid" ^< %%f') do echo %%f: %%c %%~tf
)) > LogsReceived.txt

Resources