Windowes Batch file: find line with specifies words - batch-file

I have to run script that find find partition with more than 1 GB free space.
I wrote the following:
#echo on
set isComplete = 0
set last = 0;
DISKPART /s .\script.txt > .\log.txt
for /f "tokens=3" %%f in ('.\log.txt') do (
FIND /C /I "GB" .\log.txt > %isComplete%
IF %isComplete% > 0
%last% = %%f
)
Dispart call to another script that prints to log.txt all the availble partitions.
Log.txt equals to:
Partition ### Type Size Offset
Partition 1 Primary 74 GB 1024 KB
Partition 2 Primary 300 MB 74 GB
now, i want to check which parttion has more than 1 GB free space, so I look foe "GB" word.
but I always get: > "was unexpected at this time." error.
can anyine help me to figure out what the problem? or suggest me a better way to do that?
thanks!!!

Ouch.
You've got a number of problems.
The output of LIST PARTITION gives the size and offset of each partition. I'm not very familiar with DISKPART, but I don't believe the size gives the amount of free space within the partition. It indicates how large the partition is, but gives no indication of how much space has already been allocated to existing files. The offset indicates the location of the partition. So it seems you are off on the wrong foot right from the get-go.
That being said, you have some major syntax problems in your script.
It looks like you are trying to read a file in your FOR statement, but in reality your syntax is attempting to execute a command because you enclosed the file name in single quotes. You need to type HELP FOR from the command line and read carefully the description of the FOR command.
You want either
for /f "tokens=3" %%f in (log.txt) do (
or, if the filename contains spaces (which yours doesn't), then
for /f "usebackq tokens=3" %%f in ("file name with spaces.txt") do (
Your line FIND /C /I "GB" .\log.txt > %isComplete% is attempting to write the output of the FIND command to a file named "0". I doubt that is your intention. The FIND command will print out the complete text of any line that contains your search string of "GB". It will also set the ERRORLEVEL to 0 if it finds at least one matching line, or 1 if it fails to find a matching line. I'm not sure what you are attempting to do.
Your IF statement is a mess. Here again you need to type HELP IF from the command line and read carefully how to use it. Your existing attempt has many errors
You can't extend an IF statement accross multiple lines unless you either use line continuation ^, or parentheses.
You can't use > as a comparison operator, you need to use GTR
I can't figure out exactly what comparison you are trying to make.
I don't know how to point you in the right direction because I don't understand what your overall mission is. Perhaps if you describe in more detail what you are trying to do, someone can provide a script that will accomplish the task, and you can learn from that example.
DISKPART is a potentially dangerous tool. I don't see how you can do harm with the LIST command, but other commands could create problems if misused. While you are learning the rudiments of batch scripting, I suggest you avoid DISKPART. I would hate for you to accidently corrupt your hard drive because of a batch programming mistake.

Related

What is wrong with this batch processing of the contents of a text file

This is how I have always remembered processing the CONTENTS of a file line-by-line in a batch file (backed up by web search):
for /F "delims=" %%N in ("del files.txt") do del "%%N"
It now deletes "del files.txt" and #echo %%N gives "del files.txt"
Does it have something to do with the name needing to be quoted because of the space? WTF am I missing?
("string") is used to parse strings. ("filename") can be used with usebackq. It seems you confused them in your search. So, you can write:
for /f "usebackq delims=" %%N IN ("del files.txt") do whatever you want.
Please don't accuse me of not reading help.
for /? (first thing I did) yields:
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ('string') DO command [command-parameters] MAKE NOTE THAT 'string' IS IN SINGLE QUOTES!!!
FOR /F ["options"] %variable IN (command) DO command [command-parameters]
because I just happened to lose the "if usebackq..." line because it just happened to get lost coinciding withe the "press any key..." line in my command prompt window because it just happened to be sized unfortunately (and still doesn't show file-set in standard quotes).
I was asking why quotes wouldn't be used in (file-set) when they are required for spaces and used in (file-set) without /F (i.e. for \%f in ("c\:path w spc\*.txt") do...)
I have used that exact syntax in other working batch files. though I went and checked an in each case, %1 or an environment var were in () which apparently settled how quotes were addressed.
#1 google search result: ss64.com/nt/for_f.html which in my frustration I misread the usebackq in reverse and tried ` because it went on to say
"The backquote character ` is just below the ESC key on most
keyboards"
, indicating to me that I was supposed to use that (once or twice) as quotes as seems rational to me if I'm giving direction to use that character.
I am providing this clarification in case it helps others experiencing my frustration.
Those who have "graded me down" for what I believe is legitimate confusion by doing so also prevent me from asking a different question in a totally unrelated area and I would appreciate if they would re-evaluate. I have certainly learned my lesson about unfortunate series' of events.
I understand the reasons that underlie the policy but am very frustrated that 1 time in the years I have been a member being criticized, just for poor luck IMHO, for a question should penalize me apparently 4 or 5 days.
(It's also confusing since since the message says
It's been 2 days since you asked your last question. We ask that you wait 2 days before asking again. Use this time to revisit your previous questions, editing to address any issues that folks have pointed out in comments.
Does that mean 2 more days or the two I have waited?)
So I guess if people want to pound on me for this protest, how many more days can it cost me?
And a further Thanks! to double-beep for the useful answer even if it wasn't a complete explanation.
Well, back to the penalty box...

How to output multiple lines from a FINDSTR to a variable

It's no surprise that the official documentation doesn't really help in the matter of understanding how does the command process the result of a command instead of a filelist neither why is it even called 'FOR'. Yes I already know Stack Overflow is full of similar question but apparently, since batch scripts are influenced by so many
"breaking" factors that, even as a non-batch experienced programmer, it is difficult not to get lost in the thousands exceptions and do-nots which may affect the result.
My objective, aside from learning from the best answer possible, is to formulate a generic enough question to represent the matter which is probably the most common task including the FINDSTR command:
THE QUESTION:
How do I get the output of a FINDSTR in a way that allows me to compute every result line one at the time
possibly INSIDE the loop?
The most 'generic' (batch bs-proof if you know what I mean) example I can make is the following:
Let's say this is secret_file.txt
some not interesting line
A very interesting line = "secret1";
some not interesting line
A very interesting line = "secret2";
some not interesting line
A very interesting line = "secret3";
some not interesting line
Now with the findstr command I can output every "secret" line like this:
findstr /R /C:"secret.\"" secret_file.txt
A very interesting line = "secret1";
A very interesting line = "secret2";
A very interesting line = "secret3";
But this result is just useless without further parsing right? I could have used ctrl-F over any text reader/editor
for this matter, anyway, let's say I now want to output every line ONE AT THE TIME so that I can compute it, for
example, saving every secret to a variable then using that variable somehow
(it doesn't really matter how, we can just echo it to keep things simple).
Now, everybody agrees on the fact that for this kind of task, a FOR loop is needed.
Quoting https://ss64.com/nt/for.html on the syntax, my script.bat should looks like this:
#echo off
FOR /F %%A IN ('findstr /R /C:"secret.\"" secret_file.txt') DO ECHO Batch script language is completely fine, good job Microsoft!
This just doesn't even give any output, can someone explain me why? My hypothesis was that the output from the findstr command
is in a non-compatible format with the FOR command, not like I could check or something since the source is closed and the
documentation doesn't even bother defining the word String.
I'm ready to provide any details and even edit the question to be more visible to the wanna be Microsoft-forsaken batch scripters out there.
Using "tokens=*" to strip off leading spaces this batch uses a counter to create a (pseudo) array secret[]
:: Q:\Test\2018\12\04\SO_53614102.cmd
#Echo off
set Cnt=0
FOR /F "tokens=*" %%A IN (
'findstr /R /C:"secret.\"" secret_file.txt'
) DO (
set /a Cnt+=1
call Set Secret[%%Cnt%%]=%%A
)
Set Secret[
Sample output:
> SO_53614102.cmd
Secret[1]=A very intersting line = "secret1";
Secret[2]=A very intersting line = "secret2";
Secret[3]=A very intersting line = "secret3";
As variables in a (code block) are expanded at parse time,
delayed expansion is requiered (here through a call and doubled %%)

How to compare the text lines from two files in batch

That is the identical content of my 2 txt files formatliste_droid.txt and formatliste_siegfried.txt. I want to know if all the lines till delimiter $:$ are identical 1-1, 2-2 and so on.
Z:\15_Testdateien\jhove_Script_fuer_MIX-Verzeichnisse\testfiles\BVBBV042064787\Files\E\images.jpg$;$fmt/43
Z:\15_Testdateien\jhove_Script_fuer_MIX-Verzeichnisse\testfiles\BVBBV042064787\Files\E\Van Schijndel House - English.mp4$;$fmt/199
Z:\15_Testdateien\jhove_Script_fuer_MIX-Verzeichnisse\testfiles\BVBBV042064787\Files\E\Van Schijndelhuis - Nederlands.mp4$;$fmt/199
That's my code:
#echo off
Setlocal EnableDelayedExpansion
for /f "tokens=1 delims=$;$" %%a in (formatliste_siegfried.txt) do (
for /f "tokens=1 delims=$;$" %%c in (formatliste_droid.txt) do (
if /i %%a==%%c (
echo match
pause
)
)
)
The problem is that I always get a match even if the appropriate lines are not identical
TL;DR -
Use the fc.exe command.
Details -
There are a few issues with this logic preventing you from getting the output you're looking for. The reason you only get "match" for output is because that is the only possible output - there's only one "echo" line. Adding a case else would output the number of times a line doesn't match.
That said, adding the else would be too noisy to be valuable since the large majority of the output would be "doesn't match". The logic here says "for each line of file 1, check every single line of file 2 to check for a match". For example: given 2 files which each have 100 lines, even if each line had a match in the other file, for each of the 100 outer loops, the output would be 1 "match" and 99 "doesn't match". I'll assume you don't want 100 "match" and 9900 "doesn't match".
So instead, and still considering the question being "how to compare the text lines from two files", I'd recommend using the FC.exe command. Whether batch or vanilla command line, it was designed to compare files.
Other items for consideration:
Missing double quotes around comparison items containing spaces
%%a==%%c ... should be... "%%a"=="%%c"
"delims=" can match nearly any single character, but never a contiguous multi-character group
"Setlocal EnableDelayedExpansion" isn't required as there's no dynamic use of "set"
if case is important, the use of "if /i" will break the integrity of the check

inverted question mark and findstr

I can't seem to write certain characters (inverted question marks, fancy single quote marks, ampersands) to a text file, and then to search that file for those characters. For example the following findstr doesn't find the upside down question mark item in .txt:
#echo off
echo "Cato Event - GO Beyond GDP. What Really Drives the Economy¿">c:\test.txt
findstr /I /N /C:"Cato Event - GO Beyond GDP. What Really Drives the Economy¿" c:\test.txt
pause
::chcp 1254
I've tried with various chcp commands also to no avail.
Any help appreciated.
That is a known issue with FINDSTR - Some characters provided on the command line with ANSI byte codes > 127 are transformed into a different character by FINDSTR, prior to doing the search, which causes the search to fail.
The solution is to put the search string(s) in a file and use the /L and /G options.
See the section titled "Character limits for command line parameters - Extended ASCII transformation" at What are the undocumented features and limitations of the Windows FINDSTR command?
The only other option (assuming you want to stick with native batch commands) is to use FIND instead. It has much less functionality, but it does not have the character translation issue, and I believe it should work for your simple literal search.
find /I /N "Cato Event - GO Beyond GDP. What Really Drives the Economy¿" c:\test.txt
The line numbers at the beginning of each matching line will look like [123] instead of 123:.

Batch program script problem breaks with file names with spaces

The following is a batch script that calls mp3splt (a program that splits mp3s http://mp3splt.sourceforge.net/mp3splt_page/home.php) into partitions of 5 mins long.
for /f %%a IN ('dir /b *.mp3') do call c:\PROGRA~1\mp3splt\mp3splt -t 5.0 -o output\#f+-+#n+-+#t %%a
It breaks when the mp3 files contain a space. Can anyone propose a workaround?
for %%a IN (*.mp3) do (
call c:\PROGRA~1\mp3splt\mp3splt -t 5.0 -o output\#f+-+#n+-+#t "%%a"
)
What others are saying here to quote the variable is doubtless correct. That's needed for it to work correctly. But it also is only half the solution.
Your problem here is that dir /b spits out lines of text, each one containing a single file name, like so:
foo bar.mp3
baz gak.mp3
track01.mp3
...
for /f on the other hand is made for reading files or something else (the dir output in this case) line by line ... but it also does tokenizing. That means it splits strings at configurable places into individual tokens.
By default, /F passes the first blank
separated token from each line of each
file. Blank lines are skipped. You
can override the default parsing
behavior by specifying the optional
"options" parameter. This is a quoted
string which contains one or more
keywords to specify different parsing
options. —help for
So you only get the part before the first space of the file name. You can work around that by using
for /f "delims=" in ...
to specify that tokenizing should be done with no delimiters, essentially giving you the complete line each time. But a better way is actually the one I outlined at the start to just use the regular for to iterate over the files. No surprises with spaces in file names there and it actually makes your intent a lot clearer.
I am regularly surprised why people tend to choose a convoluted and wrong solution over a simple, clear and correct one.
You can quote the variable containing the file name:
"%%a"

Resources