In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Today, I would like to share with you the relevant knowledge points of for sentence use case analysis, the content is detailed, the logic is clear, I believe most people still know too much about this knowledge, so share this article for your reference, I hope you can get something after reading this article, let's take a look at it.
I. Preface
In batch processing, for is the most powerful command statement, which makes it possible to parse text content, traverse file paths, increase / decrease values, etc.; with if, call, goto and other process control statements, you can achieve complex automated and intelligent operation of the script; reasonable use of for statements can also greatly simplify the code and save you from the pain of writing a large number of repetitive statements. The proficiency in the use of for sentences has become the most important criterion to measure a person's batch processing level.
In this series of tutorials, I will lead you into the magic door of for sentences through frequent examples in practical applications, and step by step to the magic hall of for sentences, so that in practical applications, you can independently write concise and efficient code and gallop freely in the world of batch processing.
Note: the following explanations are based on the operating system environment of Windows XP Pro SP3 in simplified Chinese.
II. Basic usage of for statement [update on November 9, 2008]
Just as the colorful lights are made up of three primary colors of red, green and blue, the most complex for statement also has its basic form, which looks like this:
In the cmd window: for% I in (command1) do command2
In batch file: for% I in (command1) do command2
The reason for distinguishing between cmd windows and batch files is that although the behavior of command statements in these two environments is basically the same, the details are still slightly different. The most obvious difference is that in the cmd window, the form variable I after for must be referenced by a single percent sign, that is,% I. In a batch file, the reference form variable I must use a double semicolon, that is,% I. For convenience, if not particularly emphasized, the following explanations take the batch file environment as an example.
Let's first look at the basic elements of the for statement:
1. For, in and do are the keywords of the for statement, and none of them are indispensable.
2.% I is a reference to a formal variable in a for statement, which must appear even if it does not participate in the execution of the statement after do.
3. After in, the parentheses before do cannot be omitted
4. Command1 represents a string or variable, and command2 represents a string, variable or command statement
By now, you may be able to write a simple for statement, such as:
Echo offfor I in (bbs.bathome.cn) do echo Ipause
Save as a batch file and execute, and you will see this message in the pop-up batch window:
[result1]
Bbs.bathome.cn
Please press any key to continue.
Soon, you will find this for statement so simple that you don't feel the power of it at all: this for statement is no different from using echoes directly!
Yes, demo code is always just a demonstration, just like most high-level language textbooks, when guiding beginners to learn, they basically tell you how to write a display hello world! Windows, from these demo code, you can't see how practical they are, you're just a little curious: Hey, there's a window popping up? After a while, you will feel dull.
Well, in order to make people more interested in for, let's first analyze some considerations of the for statement, and then let's take a look at the more powerful examples of for statements.
1. The form variable I of the for statement can be replaced with any of the 26 letters. These letters are case-sensitive, that is,% I and% I are not considered to be the same variable. The form variable I can also be replaced with other characters, but in order not to conflict with the 10 form variables of% 0%% 9 in the batch, please do not replace%% I with any one of% 9.
2. The string or variable represented by the command1 between in and do can be one or more, each string or variable, which we call an element, separated by spacebar, tab, comma, semicolon or equal sign.
3. The for statement extracts each element in command1 in turn, assigns its value to the formal variable I, and takes it to the command2 after do to participate in the execution of the command; and only one element is extracted at a time, and then the command statement after do is executed once, regardless of whether the element is brought to command2 to participate in the operation of command2. After executing the statement after the do, extract the next element in the command1, execute the command2 again, and loop until all the elements in the command1 have been extracted. The for statement ends execution.
Among them, the third point is the most critical, it describes the execution process of the for statement, is the essence of the for statement, we must keep this in mind in order to deeply understand the more complex for process.
With the above foundation, let's look at another example, which modifies some of the contents of code1, and the result will be very different:
Echo offfor I in (bbs,bathome,cn) do echo Ipause
Compared with the execution result of code1, the execution result of code2 has changed as follows:
1. The display result is divided into 3 lines (excluding the last line of Chinese prompt)
2. Each line is segmented from the comma
If you replace the dot in the string bbs.bathome.cn with spaces, tabs, or equal signs, the execution result will be the same as that of code2.
Now, let's analyze the execution of the for statement in the code2 code:
First, the for statement splits the bbs,bathome,cn string into three elements: bbs, bathome and cn with a comma as a delimiter, which determines that the statement after do will be executed three times
Then, the first execution process is as follows: first, the string bbs is taken as the value of the form variable I, and it is executed in the statement after do, that is, the echo%% I statement is executed, and the I value is bbs. Therefore, the result of the first execution will display the string bbs on the screen. The process of the second execution is the same as the first execution, except that the value of I has been replaced with the second element in command1, that is, the string bathome; in this loop, when the third echo execution is complete, the entire for statement will be completed, and at this point, the next statement, the pause command, will be executed.
In fact, this example is only a little more tricky and interesting than the previous example: the execution result of a for statement is divided into three lines!
In order to show you the real power of for, I racked my brains, posted numerous posts, missed the point, and had no choice but to show a piece of code that had been sealed at the bottom of the box for many years: detect which partitions are in the current hard disk ^ _ ^
@ echo offset str=c d e f g h i j k l m n o p q r st u v w x y zecho the partition of the current hard disk is: for% I in (% str%) do if exist% I: echo% i:pause
This code can detect which partitions are on the hard disk, including the U disk and the removable hard disk, but it will also be listed when there is a disk in the CD-ROM drive, which is a defect of this code. I will show you how to eliminate this flaw, please pay attention to the subsequent chapters of this series.
Advanced applications:
Want to know what files are in the current directory? Please use the following code:
@ echo offfor% I in (*. *) do echo "% I" pause
Do you want to list all the text files in the current directory? Please use the following code:
@ echo offfor% I in (* .txt) do echo "% I" pause
Do you want to list text files with only two characters as file names? Please use the following code:
@ echo offfor% I in (? .txt) do echo "% I" pause
Digression:
1. The easiest way to list various files in the current directory is to use the dir command. However, from the above code, you can deepen your understanding of the for statement execution process (using wildcards * and?).
2. Note: the above code cannot list files with hidden or system attributes.
Exercise: use for statements to create three text files: test1.txt, test2.txt, and test3.txt.
For more comprehensive exercises, please see this post: for sentences from getting started to mastering matching exercises
In order to cooperate with the introduction to proficiency of for sentences, this topic is specially opened. The explanation of each part of the for tutorial gives a number of targeted exercises here to facilitate beginners to quickly master the usage of for sentences. This exercise does not pursue quantity, but gives specific topics for the various technical details of the for statement, and strives to cover the technical points of the for statement.
This exercise only mentions the role of outline. In order to write more efficient and refined code, you need to speculate carefully in practical application and try to solve more than one problem.
In order to facilitate others to use for reference, please indicate the title number before each code in the reply.
The basic usage section of the A:for statement (please use a simple for statement to answer the questions in this section):
A1: suppose set str=I love,bbs;bathome=net, please show the five strings I, love, bbs, bathome and net, respectively. Objective: to understand which symbols are used as delimiters for elements in for statements.
A2: the condition is the same as A1, requiring that only the string net is displayed at the end. Objective: to understand the execution flow of for statement.
Third, text analysis shows magical power: detailed explanation of the usage of for / f
Preface
For / f is a very powerful guy.
If the for statement is the most powerful statement in batch processing, then for / f is the essence of the essence.
The strength of for / f is closely related to its numerous switches. Because there are so many switches, the usage is complex. This chapter will be divided into several sections to introduce the powerful for / f statements one by one.
(1) born to parse the text: the basic usage of for / f
All objects, whether files, forms, or controls, are nothing more than text messages such as "c:\ test.txt" or "CWnd" in all non-machine languages, while all objects, such as a configuration information in an ini file, a key value in the registry, a record in a database, etc. Only when it is transformed into text information with a certain format can it be identified and manipulated by the code. It can be said that a large part of the work of programming is racking their brains to figure out how to extract this text information.
On the other hand, extracting text information is for / f's specialty: reading file contents; extracting certain lines of characters; intercepting a certain character fragment; dividing, disrupting and mixing the extracted content. For / f will try to do whatever you can think of, because for / f is designed to parse text.
Let's take a look at an example.
If you have a text file, test.txt, the contents are as follows:
[txt1]
The goal of the forum is not to seek the largest, but the best, to be the most practical batch forum.
Forum address: bbs.bathome.cn.
Here is: the blessed land for beginners to advance, and the paradise for experts to talk about swords.
Then, save the following code as test.cmd and run it in the same directory as test.txt, and the contents of test.txt will be displayed as is on the screen:
@ echo offfor / f% I in (test.txt) do echo% ipause
The main purpose of this code is to set up an idea: to read the contents of a text file, please use the for / f statement!
Advanced topic: the for / f statement shows the whole test.txt at once?
In this code, although the result of the execution is to show everything in the test.txt, it looks like the for / f statement displays the entire test.txt on the screen at once, but in fact it is not.
No matter how the for statement changes, its execution still follows the basic for process: each element is processed in turn until all elements are processed. It's just that in the for / f statement, the element here refers to each line in the file, that is, the for / f statement processes the text file in behavioral units. This is a very important rule, and its importance was emphasized in the previous chapter. I hope you can always keep this principle in mind in the following learning process, so that many problems will be easily solved. The following is the demo code to verify this statement (adding the & pause statement to [code4]):
@ echo offfor / f% I in (test.txt) do echo% i&pausepause
(2) A sharp weapon for segmenting strings: delims=
Maybe you disdain the [code4] code: doesn't it just show the contents of the test.txt? It doesn't seem to be of much use.
All right, let's do a magic trick.
Or the text of [txt1], modify [code4]:
@ echo offfor / f "delims=," I in (test.txt) do echo ipause
Run test.cmd again. Do you see any changes?!
[result2]
The goal of the forum is: do not seek the maximum
Forum address: bbs.bathome.cn.
Here is the blessed place for beginners to advance to the next round
Please press any key to continue.
As a result, you are surprised to find that everything after the first comma of each line is gone (if there is no comma, leave it as is), that is, you have successfully extracted everything before the first comma of each line!
Imagine, what is the use of this code?
How useful it will be if someone gives you a software list and each line is in the format of "English software name (comma) Chinese software name", but you only want to keep the English name. And suppose that there is such an IP file, the first column is the numerical format of the IP address, the second column is the specific space address, column and column separated by commas, and you want to extract the numeric format of IP, ha ha, I do not say you know how to do it?
If the text is not separated by commas, but by other symbols, then the comma of "delims=," can be replaced with the corresponding symbol.
Here, we introduce a new switch: "delims=,", which means that a comma is used as the delimiter of the string being processed.
In batch processing, the way to specify delimiters is to add a switch shaped like a "delims= symbol list" so that each line of string being processed is split by the symbols listed in the symbol list.
It is important to note that if the switch "delims= symbol list" is not specified, the for / f statement defaults to the space bar or tab key as the delimiter. Please change the punctuation marks in different positions in [txt1] to spaces or tabs, and then run [code4] to try.
Advanced topic: what if I want to specify more than one symbol?
In the above explanation, I mentioned a way to specify a separator: add a switch that looks like a "delims= symbol list". I don't know if you've noticed, but I said "symbol list" instead of "symbol", which is very fastidious, because you can specify more than one separator at a time!
Let's take [txt1] as an example and transform [code6] again:
@ echo offfor / f "delims=.," I in (test.txt) do echo ipause
The results show that:
[result3]
The goal of the forum is: do not seek the maximum
Forum address: bbs
Here is the blessed place for beginners to advance to the next round
Please press any key to continue.
In this way, the content before the first period or the first comma is extracted.
[code7] the execution process is: read the contents of the test.txt line by line, split each line with a dot and comma (if there is no line with a dot or comma, then no longer split, for the convenience of description, we will split a string segment by a dot or comma, called a section), and then for / f will extract the contents of the first section as the final result, displayed on the screen. It should be noted that here, the string of all lines is split into more than two sections, but the code of [code7] only extracts the contents of the first section of the string, because the for / f statement only extracts the first section of the string by default.
(3) fixed-point extraction: tokens=
When I explained delims= in the previous section, I repeatedly emphasized that for / f can only extract the content of the first section by default. Now let's think about a question: what if what I want to extract is not in the first section?
This time, it's tokens= 's turn.
Tokens= is usually followed by numbers, such as tokens=2, or multiple numbers, but each number is separated by a comma, such as tokens=3,5,8, which means: extract section 2 strings, extract sections 3, 5, and 8 strings. Note that the "section" mentioned here is divided by the delims= switch, and its content is not immutable.
Let's look at an example:
[txt2]
The ruler has its shortcomings, the inch has its strong points, it is non-negotiable to learn batch processing well, complicate the consideration of problems, and simplify the solution of problems.
For the text [txt2], suppose they are saved in the file test.txt. If I want to extract the sentence "learn batch processing without negotiation", how can I write code?
If we look at [txt2] a little bit, we will find that if we use a comma as a syncopation symbol, we can just turn "learned batch processing non-negotiable" into a separate "section". Combined with the explanation of the previous section, we know that the switch "delims=," is indispensable, and the content to be extracted is in section 3, which is syncopated with commas, so the number after tokens= should be 3, and the final code is as follows:
@ echo offfor / f "delims=, tokens=3" I in (test.txt) do echo ipause
What if we are going to extract not only one "section", but more than one? For example, is it written like this to extract sections 2 and 5 strings split by commas?
@ echo offfor / f "delims=, tokens=2,5" I in (test.txt) do echo ipause
After running the batch, it is found that the execution result shows only the contents of section 2.
It turns out that the% I after echo only receives the string represented by the first value 2 in tokens=2,5, while the string represented by the second value 5 cannot be displayed in the execution result because there is no variable to receive it.
So, how do you receive what is referred to by multiple values after the tokens=?
The for / f statement provides for this situation as follows:
If more than one number is specified after the tokens=, if the form variable is% I, the content of the first number reference is received with the first form variable% I, the content of the second number reference is received with the second form variable% j, and the content of the third number reference is received with the third form variable% k. The content of the Nth numeric reference is received by the Nth formal variable, where the formal variable follows the alphabetical order, and the symbol of the Nth formal variable is determined by the first formal variable: if the first formal variable is% I, then, the second formal variable is%% j; if the first formal variable uses% x, then the second formal variable is% y.
Now looking back at [code9], you should know how to modify it to meet the requirements of the topic, right? The modification results are as follows:
@ echo offfor / f "delims=, tokens=2,5" I in (test.txt) do echo I jpause
If there is a requirement to display the contents of [txt2], but the comma is to be replaced with a space, how do you write code?
Combined with what you have learned above, with a little thought, you may soon have the answer:
@ echo offfor / f "delims=, tokens=1,2,3,4,5" I in (test.txt) do echo I j k l mpause
After writing, you may realize the question: if the number of "sections" to be extracted is not 5, but 10, or 20, or more, do I have to write from 1 to 10, 20 or more? Is there a more concise way to write it?
The answer is yes, that is: if the content to be extracted is consecutive multiple "sections", then the consecutive numbers can only write the minimum and maximum values, with a short horizontal connection in the middle, for example, tokens=1,2,3,4,5 can be abbreviated to tokens=1-5.
You can also make this expression a little more complicated: tokens=1,2-5 meme tokensteen 1-3 meme 4jue 5jour 1-4ju 5. Write it as it is convenient.
You may also see a rather strange way of writing:
@ echo offfor / f "delims=, tokens=1,*" I in (test.txt) do echo I jpause
As a result, the first comma is gone, replaced by a space symbol, and the rest remains the same.
The secret lies in this asterisk.
The asterisk followed by the tokens= has the function that the string is split from left to right into the number of sections represented by the value before *, the rest of the string remains the same, and the whole is received by a variable represented by *.
Theoretical explanation is rather boring, especially for the sake of strictness, and a lot of finite modifiers are used, resulting in long sentences and increasing the difficulty of understanding. Let's explain it in combination with [code12].
The content of [txt2] is segmented, and the syncopation symbol is a comma. After the first section, the syncopation does not continue, because in tokens=1,*, the asterisk is followed by the number 1; after the first section of the string is split, the rest of the string is not divided as a second section string, so that [txt2] is divided into two sections, which are received by the variable% I and the variable% j, respectively.
The above segmentation methods can be used together. I don't know if you can understand the meaning of the following code. If you don't, run the code and figure it out over and over again. You will certainly have a deeper understanding of what is explained in this section:
@ echo offfor / f "delims=, tokens=1,3-4 lpause *"% I in (test.txt) do echo% I% j% k% lpause
(4) skip the irrelevant content and go straight to the topic: skip=n
In many cases, useful information is not always throughout the text, but in the line after line N, in order to improve the efficiency of text processing, or without interference from redundant information, for / f allows you to skip these useless lines and start processing directly from line N + 1. In this case, you need to use the parameter skip=n, where n is a positive integer indicating the number of lines to be skipped. For example:
@ echo offfor / f "skip=2" I in (test.txt) do echo ipause
This code will skip the first two lines and display the information in the test.txt from line 3.
(5) ignore the line that begins with the specified character: eol=
Type: for /? in the cmd window, and the explanation is as follows:
Eol=c-refers to the end of a line comment character (just one) [/ quote] [quote] FOR / F "eol=; tokens=2,3* delims=,"% I in (myfile.txt) do @ echo% I% j% k
Each line in the myfile.txt is analyzed, ignoring those that begin with a semicolon.
The first explanation is nonsense and puzzling: what does the end of a line comment character mean? what's going on with "(just one)"? Combined with the second explanation, we know that eol has the ability to ignore the specified line. However, the two interpretations contradict each other: do you ignore lines that start with a specified character or ignore lines that end with a specified character?
Practice is the only criterion for testing truth, so let's use code to test the role of eol:
@ echo offfor / f "eol=;" I in (test.txt) do echo ipause
As a result, lines that start with a semicolon are not displayed.
Thus, the second explanation is correct, and the exact meaning of eol= is to ignore lines that begin with a specified character. And the "end" of the first article is pure Microsoft talking out of its mouth.
So, how to explain "(just one)"?
Try this code:
@ echo offfor / f "eol=,;" I in (test.txt) do echo ipause
At this point, the screen should not appear at this time; ". The error message. It can be seen that only one character can be specified-in many cases, I complain about such a design and can do nothing about it: why can only one be specified instead of more? To ignore multiple if and findstr plus pipes to filter multiple times, the efficiency is too low-basically all the features you can use are provided, but you can't do better. Batch processing, why is your function so weak?
I don't know if you've noticed that if there are lines in test.txt that start with a semicolon, those lines will disappear in the execution result of the code [code14].
It turns out that the for / f statement ignores the contents of lines that begin with a semicolon by default, just as it defaults to the space bar or tab key as the syncopated character of the string.
In many cases, we can make full use of this feature. For example, when designing a configuration file to be read with for, we can add a semicolon at the beginning of the comment text. For example, when writing virus file killing code, we can read the list of virus files through the for statement. Then, the configuration file of virus file list .ini can be written as follows:
The following are common virus files, please see one to kill one ^ _ ^
; copyleft: no
Qq.exe
Msn.exe
Iexplore.exe
If you want to cancel this default setting, you can choose to:
1. Specify another character for eol=
2. Use the for / f "eol=" statement, that is, force the specified character to be empty, just like with delims=.
(6) how to decide which sentence pattern of for / f should be used? (also on the use of usebackq)
For / f% I in (…) Do (…) There are several deformations of statements, but the difference lies in the contents of the first parenthesis: some are enclosed in single quotation marks, some are enclosed in double quotation marks, and some are not wrapped in any symbols in the following format:
1. For / f% I in (filename) do (…)
2. For / f% I in ('command statement') do (...)
3. For / f% I in ("string") do (…)
Seeing here, I think many people may have begun to get confused: if you want to solve a specific problem, faced with so many choices, how to decide which one to use?
In fact, when I listed these statements above, I already had a hint, and I don't know if you've noticed.
If you can't understand the secret at the moment, it doesn't matter. Please listen to me one by one.
1. When you want to read the contents of a text file, you should use the first statement without any symbols in the first parenthesis; for example, if you want to display the contents of test.txt, use for / f% I in (test.txt) do echo% I
2. When you read the contents of the execution result of the command statement, the command statement in the first parenthesis must be wrapped in single quotation marks and the second statement should be used; for example, when you want to display a text file with a test string in the file name in the current directory, you should use statements such as for / f% I in ('dir / a murd / b * test*.txt') do echo% I
3, when you are dealing with a string, the contents of the first parenthesis must be enclosed in double quotes, which should be the third statement; for example: when you want to change the dot in the string of bbs.bathome.cn characters into dashes and display them, you can use statements such as for / f "delims=. tokens=1-3"% I in ("bbs.bathome.cn") do echo%% i-%%j-%%k.
Obviously, whether the first parenthesis needs to be wrapped in symbols, and what kind of symbols are used, depends on the type of object being processed: if it is a file, there is no need for a package; if it is a command statement, it is wrapped in single quotation marks; if it is a string, it is enclosed in double quotes.
Of course, this is not absolutely the case, and if you think carefully of the difficult special characters in batches, you will definitely have a big head.
Maybe you have a big headache in a flash in your head: in the first sentence, what if the file name contains spaces or &?
Is it the same?
Try a file called test 1.txt.
You quickly write the code, create a new file-- > codeword-- > save it as a batch, which takes less than 1 minute:
@ echo offfor / f% I in (test 1.txt) do echo% ipause
You excitedly double-click the batch, and after running it, a shameful error message appears on the screen: the system cannot find the file test.
When you replace test 1.txt with test&1.txt, something even weirder happens: the CMD window flashes before your eyes, and then it disappears gracefully.
You may feel that your code has written some wrong symbols, you check it carefully again to make sure there is no clerical error, and then you double-click the batch again, and the problem remains the same; you begin to suspect that other programs may affect it, so close the other windows and run it again, and the problem remains the same; you run it several times in a row, and it's the same result.
How strange!
As soon as you pat your thigh, you suddenly think of something: when the path contains special characters, you should use quotation marks to enclose the path. Yes, this is it!
But when you write the code, you quickly get lost: for / f% I in ("test 1.txt") do echo%% I, isn't that the format of the third for / f command mentioned above? The batch will recognize the file name test 1.txt as a string.
You boredom type for /? in the CMD window, hit enter heavily, and aimlessly search for help messages, hoping to find something.
It really got you something.
You see a description like this:
Usebackq-specifies that the new syntax has been used in the following class cases:
Execute a string in quotation marks as a command and a single
The quotation mark character is a text string command and is allowed in filenameset
Use double quotation marks to expand the file name in.
However, after reading through it, you feel like you are in a fog and you don't know what to say.
Fortunately, here is an example with a simple explanation:
FOR / F "usebackq delims=="% I IN (`set`) DO @ echo% I
Enumerates the environment variable names in the current environment.
You have carefully compared the differences in the writing of for / f statements with and without usebackq, and you will soon find the answer: after using usebackq, if the first parenthesis is a command statement, then change the single quotation mark'to the back quotation mark `(the key below the esc key in the upper left corner of the keyboard, in the same key position as ~).
Looking back at the description of usebackq, you finally deciphered it: usebackq is an enhanced parameter. After using this parameter, the first parenthesis in the original for statement should be changed as follows: if the object in the first parenthesis is a command statement, the original single quotation mark 'should be changed to the closing quotation mark'. If the object in the first parenthesis is a string, the original double quotation mark "should be changed to single quotation mark"; if the object in the first parenthesis is a file name, it should be enclosed in double quotation marks.
To verify, rewrite [code17] into the following code:
@ echo offfor / f "usebackq" I in ("test 1.txt") do echo ipause
The test passed!
At this point, you are likely to look up to the sky and sigh: Shit, the damn machine translation of Microsoft!
As for replacing the space in the [code17] code with &, the CMD window will exit directly because & is the connector of the compound statement. When preprocessing, CMD will first parse the & before and after as two statements rather than a complete for statement, resulting in serious syntax errors. Because it involves the issue of preprocessing mechanism, it does not belong to the content to be discussed in this section, so I will not explain it in detail here.
At this time, we will be surprised to find that there are as many as six sentence patterns in just one for sentence:
1. For / f% I in (filename) do (…)
2. For / f% I in ('command statement') do (...)
3. For / f% I in ("string") do (…)
4. For / f "usebackq"% I in ("File name") do (…)
5. For / f "usebackq"% I in (`Command statement `) do (…)
6. For / f "usebackq"% I in ('string') do (…)
Among them, 4, 5 and 6 developed from 1, 2 and 3, and they have the corresponding relationship as follows: 1 Murray-> 4, 2 Murray-> 5, 3 Murray-> 6.
Fortunately, the latter three situations are not commonly used, so it is OK to firmly grasp the application of the first three sentence patterns, otherwise, it is a bit confusing to determine which sentence to choose among so many sentence patterns.
As for why for / f adds the usebacq parameter, I only found a reasonable explanation for the fourth statement: to be compatible with spaces or & in the file name. I do not quite understand why it is still necessary to exist in clauses 5 and 6, which remains to be discovered by you.
(VII) delayed detailed explanation of variables [2009.2.12 update]
Variable delay plays a vital role in for statements, not only in for statements, but also in other compound statements, it also works silently behind the scenes. In order to highlight its importance, this section is posted on separate floors, hoping to attract your attention.
For beginners in batch processing, the concept of "variable delay" may be unheard of, but it is like an invisible wall on your way forward. You can't feel it, but when you try to rush forward, it will bounce you back so hard that you can't cross it and return without success. Once you find a way to get over it, you will find that in the world of for, there is already a smooth road ahead, and your understanding of batch processing has risen to a new level.
For example, you write a code like this:
@ echo offset num=0&&echo% num%pause
Your intention is to display the value after assigning a value to the variable num. As a result, instead of showing 0, it shows that ECHO is off.
The reason for the error is that the guy "variable delay" is doing something wrong.
Before we talk about variable latency, we need to understand the execution process of batch processing, which will help us to understand variable latency in depth.
What is the execution process of batch processing?
"from top to bottom, one by one", I think, this classic saying is already familiar to everyone. When you have nothing to do, you can read it backwards, and there is no ancient rhyme. However, what I want to ask you is, do you really understand the meaning of this sentence?
"Top-down", which has little to do with our explanation in this section, will not be mentioned for the time being. The latter, "execution one by one" has a lot to do with variable delay, and it is the focus of this section.
Many people tend to think that a line of code is a statement and equate "line-by-line execution" with "line-by-line execution", which is a big mistake.
Is there a mystery hidden in "one-by-one execution"?
Exactly.
"Article by item" is not the same as "line by line". This "article" means "a complete statement" and does not mean "one line of code". In batch processing, whether it is a complete statement or not is not in terms of rows, but depends on its scope.
What kind of statement is "a complete statement"?
1. In a compound statement, the whole compound statement is a complete statement, no matter how many lines the compound statement occupies. Common compound sentences are: for statement, if. Else statements, statements connected with connectors &, |, and & &, statements connected with pipe symbols |, and blocks of statements enclosed in parentheses and composed of multiple statements
2. In a non-compound statement, if the statement occupies the position of a line, the line of code is a complete statement.
For example:
@ echo offset num=0for / f% I in ('dir / a num+=1 echo num / b *. Exe') do (the current value of set / a num+=1 echo num is% num%) there are% num% exe files in the current directory dir / Amurd / b * .txt | findstr "test" > nul&& (there is a text copy containing test string in echo) | | echo does not have a text file if exist test.ini containing test string (echo exists test. Ini file) test.ini file pause does not exist in else echo
The above code has 14 lines, but there are only seven complete statements, which are:
Article 1: echo statement on line 1
Article 2: set statement on line 2
Article 3: for compound statements on lines 3, 4, 5 and 6
Article 4: echo statement on line 7
Article 5: use & & and | | join compound statements on lines 8, 9 and 10
Article 6: if on lines 11, 12, 13. Else compound statement
Article 7: the pause statement on line 14.
Here, I have to spend so much space to explain that a line of code is not necessarily a statement, because batch execution is characterized by "line-by-line" execution rather than "line-by-line" execution, which clarifies this misunderstanding. will have a better understanding of batch preprocessing mechanisms.
During the "itemized" execution of the code, cmd.exe, the batch interpreter, does some preprocessing for each statement, which is the famous "preprocessing mechanism" in batch processing. The general situation of preprocessing is as follows: first, read a complete statement into memory (no matter how many lines the statement has, they will be read together), and then identify which parts are command keywords, which are switches, which are parameters, and which are variable references. If the code syntax is incorrect, give an error prompt or exit the batch environment; if it passes smoothly, then put all the referenced variables in the statement and the percent sign pairs on both sides of the variables, replace it with the specific value that has been assigned to the variable since the statement is read into memory. When all the preprocessing work is completed, the batch will perform the original functions of each command within each complete statement. That is, if the command statement contains a variable reference (the variable and the percent sign pair next to it), and the value of a variable is changed during the execution of the command, even if the variable is used elsewhere within the statement, they will not be replaced with the latest values, because when a statement is preprocessed, all variable references have been replaced with string constants The value of the variable is changed within the compound statement and does not affect anywhere else inside the statement.
By the way, after running the code [code20], it will display on the screen how many exe files are in the current directory, whether there is a text file with a test string, and whether there is a test.ini file. What puzzles many people is that if there are exe files in the current directory, how many exe files there are, how many times the screen will prompt "num current value is 0" instead of displaying 1 to N (N is the number of exe files).
Combined with the above two examples, let's analyze again why there is some gap between the execution results of these two pieces of code and our expectations.
In [code19], set num=0&&echo% num% is a compound statement that means: assign 0 to the variable num, and when successful, display the value of the variable num.
Although the value of the variable num is displayed only after the variable num is assigned successfully, because this is a compound statement, the% num% after & & can only be replaced by the specific value of the variable num assigned by the statement before the set statement, but not by the value assigned to the num by the set statement inside the compound statement and before the set statement, so it can be seen that this num is not that num. However, we did not assign a value to the variable num before this compound statement, so the% num% after & & is null, which means that only the echo command was executed after & &, so the current state of the echo command is displayed instead of the value of the variable num (although the value of the variable is changed by the set statement).
In [code20], the meaning of the for statement is to enumerate the exe files in the current directory. Each time an exe file is found, the value of the variable num accumulates by 1 and the value of the variable num is displayed.
After reading the analysis of [code19], it is no longer so difficult to analyze [code20]: the code on lines 3, 4, and 5 constitutes a complete for statement, and the statement "echo num's current value is the interior of the compound statement for where" num% "and" set / a num+=1 "are co-located, so after set changes the value of num on line 4, it does not have any effect on the variable num on line 5, because in the preprocessing phase. The variable reference% num% on line 5 has been replaced by the specific value assigned to the variable num before for, and it has been replaced with 0 (given by the set statement on line 2).
What if you want the code [code19] to show the value assigned to num in the execution result of & &, and let the code [code20] display the number of exe files from 1 to N when enumerating exe files?
For the code [code19], you can split the & & join compound statement into two separate statements, written as follows:
@ echo offset num=0echo% num%pause
However, this is not what we want this time.
The way to apply to both pieces of code is to use variable delay extension statements to delay the extension behavior of variables to get the value we want.
Here, let's first recharge and see what "variable expansion" is all about.
In the original words of batch processing talent willsort in CN-DOS, that is: "in many visible official documents, a pair of percent signs are used to close environment variables to complete the replacement of their values, which is called" expansion ". This is actually a first-party concept, which is called from the point of view of the command interpreter, and from the point of view of our users. You can think of it as a Reference, Call, or Get. " (see: under what circumstances should variable delay be used? Http://www.cn-dos.net/forum/viewthread.php?tid=20733) to put it bluntly, the so-called "variable extension" is actually a very simple thing: replace the referenced variable and the pair of percent signs immediately around it with a specific value.
Since we can get the desired results by delaying the extension behavior of variables, what is the specific approach?
In general, the extension behavior of delay variables can be selected as follows:
1. Use setlocal enabledelayedexpansion statements in appropriate places
2. Use the call statement where appropriate.
Using the setlocal enabledelayedexpansion statement, [code19] and [code20] can be modified to:
@ echo offsetlocal enabledelayedexpansionset num=0&&echo! numb pausehorse echo offset num=0setlocal enabledelayedexpansionfor / f% I in ('dir / a murd / b * .exe') do (the current value of set / a num+=1 echo num is! num!) there are% num% exe files under the current echo directory dir / an exe d / b * .txt | findstr "test" > nul&& (there is a text with test string in echo) | echo does not have a text containing test string. Piece if exist test.ini (echo exists test.ini file) else does not exist test.ini file pause
Using the first call statement, then [code19] and [code20] can be modified to:
@ echo offset num=0&&call echo% num%%pause@echo offset num=0for / f% I in ('dir / a murd / b * .exe') do (the current value of set / a num+=1 call echo num is% num%%) echo has% num% exe files dir / a murd / b * .txt | findstr "test" > nul&& (there is a text copy containing test string in echo) | echo does not contain test string. Text file if exist test.ini (echo exists test.ini file) else does not exist test.ini file pause
Thus, if you use the setlocal enabledelayedexpansion statement to delay variables, you should change the variable reference that was closed using the percent sign pair to the exclamation point pair; if you use the call statement, add the call command to the front of the original command, and change the single-layer percent sign pair referenced by the variable to two-tier. Among them, because the call statement uses a double percent sign pair, it is easy to make people confused, so it is used less, commonly used is to use the setlocal enabledelayedexpansion statement (set is the meaning of setting, local is the local meaning, enable is the meaning of can, delayed is the meaning of delay, expansion is the meaning of extension, together, that is: let the variable become a local variable, and delay its extended behavior).
Through the above analysis, we can know:
1. Why use variable delay? Because we want the variables inside the compound statement to be aware of the change in the value of the variable in real time.
2. Where do you need to use variable delay statements? Within a compound statement, if the value of a variable changes, and the changed value needs to be used elsewhere within the compound statement, then you need to use a variable delay statement. The compound statements are: for statement, if. Else statements, statements connected with connectors &, |, and & &, statements connected with pipe symbols, and blocks of statements enclosed in parentheses and composed of multiple statements. The most common occasions are for statements and if. Else statement.
3. How to use variable delay?
There are two ways:
① uses the setlocal enabledelayedexpansion statement: use setlocal enabledelayedexpansion before getting the variable value statement, and change the reference to the closed variable using the percent sign to use the exclamation point pair to close
② uses the call statement: add the call command to the front of the original command and change the single-layer percent pair referenced by the variable to two-tier.
Variable delay is a very important mechanism in batch processing. It is generated from the preprocessing mechanism and is used in compound statements, especially in powerful for statements. Only by using this mechanism skillfully can we be like a fish in water in the world of for. Please climb to another tall building for your batch processing level. Very often, we have been obsessed with the handling mechanism of for. Even if we get something, it can only be explained in words. I hope you can speculate over and over again, practice more, and the experience in many details can only be obtained through a lot of groping. Good Luck!
This section refers to this article in principle: under what circumstances should variable delay be used? Http://www.cn-dos.net/forum/viewthread.php?tid=20733, the address in this forum is: http://bbs.bathome.cn/viewthread.php?tid=2899
Special thanks: willsort.
Fourth, rummaging through the folder: for / r
(1) the function and usage of for / r
According to the prose in the help message, the function of for / r is "recursion". Let's change to a more popular one, which is called "traversing folders".
A more detailed explanation is: in the following statement, if there is only a period in the "set of elements", then the purpose of this statement is to enumerate the "directory" and all the subdirectories below it. Execute the command statements in the Command statement set on these folders. Its function is similar to the "dir / ad / b / s path" function embedded in for / f compound statements. If "directory" is omitted, the operation described earlier will be performed under the current directory.
[quote]
For / r directory I in (collection of elements) do command statement collection
[/ quote]
Let's start with a code to enhance the impression:
@ echo offfor / r d:\ test% I in (.) Do echo ipause
The result of the execution is as follows:
[quote]
D:\ test\.
D:\ test\ 1\.
D:\ test\ 2\.
D:\ test\ 3\.
[/ quote]
The effect is to show the d:\ test directory and the paths to all subdirectories below it, which is similar to dir / ad / b / s d:\ test. To talk about the difference between the two, you can sum up three points:
1. The paths enumerated by for / r have slashes and periods at the end, but the dir statement does not, which will affect the further processing of the acquired paths.
2. For / r cannot enumerate directories with hidden attributes, while dir statements can obtain directories with specified attributes by specifying the parameters immediately following / a, which is more flexible.
3. If you want to further process the acquired path, you need to put the dir statement into the for / f statement and write it as for / f% I in ('dir / ad / b / s') do. Because the for / r statement enumerates paths while processing, there is no pause in the early stage when dealing with a large number of paths, while the for / f statement needs to wait until the dir / ad / b / s statement enumerates all the paths before reading them into memory for processing, so when dealing with a large number of paths, there will be obvious pauses in the early stage.
The second difference is easy to be overlooked, resulting in omissions when listing paths with for / r, while the third will give you a more intuitive feeling and it is easy to feel the difference between the two.
What if "element set" is not a period? So what?
Take a look at this code:
@ echo offfor / r d:\ test% I in (a b c) do echo% ipause
The result of the operation is:
[quote]
D:\ test\ 1\ a
D:\ test\ 1\ b
D:\ test\ 1\ c
D:\ test\ 2\ a
D:\ test\ 2\ b
D:\ test\ 2\ c
D:\ test\ 3\ a
D:\ test\ 3\ b
D:\ test\ 3\ c
[/ quote]
Originally, it means: enumerate d:\ test and all its subdirectories, add a, b, c to all directory paths, and then display them.
Let's take a look at another code:
@ echo offfor / r d:\ test% I in (* .txt) do echo% ipause
The result of the operation is:
[quote]
D:\ test\ test.txt
D:\ test\ 1\ 1.txt
D:\ test\ 1\ 2.txt
D:\ test\ 2\ a.txt
D:\ test\ 2\ b.txt
D:\ test\ 3\ 1.txt
[/ quote]
The meaning of this code is to enumerate the txt text files under d:\ test and all its subdirectories (folders ending in .txt will not be listed).
Let's go back and sum up the function of this sentence:
[quote]
For / r directory I in (collection of elements) do command statement collection
[/ quote]
The purpose of the above statement is:
1. Enumerate the "directory" and all the subdirectories under the directory path, and splice the listed directory path and each element in the set of elements into a new string in the format of "directory path\ element". Execute each command in the Command statement set for each such new string
What's special: when a "collection of elements" has a wildcard separated by a dot? Or *, treat the "element collection" as a file (not as a folder), and the purpose of the whole statement is to match the matching files under the folder referred to by the "directory" and all its subfolders; if it is not separated by a period, the "element collection" is regarded as a folder (not as a file).
2. When "directory" is omitted, it is directed against the current directory.
3. When there is only one period in the element collection, only the directory path will be enumerated.
(II) for / r or dir / ad / b / s? How to choose when enumerating catalogs
As mentioned earlier, when enumerating directories, the effects of for / r and dir / ad / b / s are very similar, which raises a question: when I want to get the directory path and do further processing, how should I choose between the two?
As a matter of fact, there has been some discussion on this issue before, and now let's make a detailed analysis.
Let's take a look at the advantages and disadvantages of each:
1 、 for / r:
1) advantages:
① can simultaneously obtain directory path and process directory path with only one statement.
When ② traverses a folder, it enumerates and processes it at the same time. When it gets a path, it processes one path. It takes up less memory and does not cause a sense of pause when dealing with a large number of paths.
2) disadvantages:
① cannot get a directory with hidden attributes, resulting in omission
② cannot get a directory with the specified attribute
2 、 dir / ad / s:
1) advantages:
① can get directories with arbitrary attributes at one time without omission.
② can get directories with arbitrary attributes by specifying different parameters, which makes it more flexible.
2) disadvantages:
The ① dir / ad / s statement can only get the directory path. In order to achieve further processing, it needs to be embedded in the for / f statement. The writing method is not concise enough.
After ② embeds the for / f statement, it needs to be written as for / f "delims="% I in ('dir / ad / b / s') do... The format is restricted by the running mechanism of for / f statements, so it is necessary to list all the paths into memory before further processing each path. When dealing with a large number of paths, the amount of memory is too large, and it will produce obvious sense of pause in the early stage, and the user experience is not good enough.
Based on the above analysis, the following choices can be made:
1. Select the dir / ad / b / s statement just to get the path to a folder and all its subfolders
2. If you need to filter folders with hidden attributes, both for / r and dir statements can be implemented, but for / r is the best choice because of its small memory footprint and fast processing speed.
3. If you need to get all folders, you have no choice but dir / ad / b / s, because the for / r statement will miss folders with hidden attributes
In practical use, I prefer to use the combination of for / f and dir because it does not cause omissions and gives me a more flexible way to deal with it. The only thing I have to put up with is its sense of pause when dealing with a large number of paths and the slightly high memory footprint behind it. When I'm in pursuit of speed and can ignore directories with hidden attributes, I switch to for / r, but this is rare-- who wants to tolerate omissions in pursuit of speed?
5. Exists only to match the first-tier directory: for / d
/ d in for / d, the complete meaning is / directory, which is intended to deal with folders, and its complete statement should look like this:
[quote]
For / d I in (collection of elements) do command statement collection
[/ quote]
When the element set contains wildcards? Or *, it matches folders, but for / d at this time is pitifully less useful than for / r: it can only match first-level folders under the current directory, or folders at a specified location, not deeper subfolders.
For example, statements such as for / d% I in (d:\ test*) do echo%% I will match to folders such as: d:\ test, d:\ test1, d:\ test2, and if such a path does not exist, there will be no echo.
When the element collection does not contain any wildcards, it acts like a statement such as "for% I in (element collection) do command statement collection".
As a result, the role of for / d becomes subtle: when a "collection of elements" contains wildcards? Or *, its function is to match the folder. At this time, it can only match the first-level folder under the current directory, or the folder at the specified location, which is not as deep as for / r, but as bad-tempered as for / r: it cannot match folders with hidden attributes; it is not as flexible as the combination of for / f and dir. When the element collection does not contain any wildcards, it is exactly "for% I in (element collection) do..." A copy of the statement, but a little more complicated.
The function of for / d is so limited and I use it so few times that for a time I couldn't find the opportunity to display its ability. I thought it was tasteless to eat, but it was a pity that it was a chicken rib.
One year and one month, I wrote this code in the cmd window:
For / d% I in (test*) do @ echo% I
My intention was to see how many test folders have been created over the years of testing in my temporary directory so that I could then replace echo with rd to delete it. At this point, I found that the code was so concise that it could not be replaced by for / r or the combination of for and dir / ad / b (you can delete these test directories by replacing echo with rd).
The joy of concise code lasted only a little more than 10 seconds, and I began to get confused-there seems to be very little and nothing to say about the similar situation in which for / d can be used.
6. Counting cycle: for / l
/ l, the abbreviation of / loop is also, translated from bird language, loop means loop. In fact, all for statements can be thought of as "loops", but in / l, it means to loop a specified number of times.
The complete format of the for / l statement is as follows: for / l%% I in (XMagneyMagnez) do (…) In this statement, x, y, and z can only be integers, either positive or negative, x refers to the starting value, y refers to the step size, and z is the ending value, which means that the statement after do will be executed as many times as the integer value closest to z, counting from x to y.
To give a specific example:
For / l% I in (1mem2mem10) do echo bathome
In the above code, the initial value is 1, the step size is 2, and the termination value is 10, indicating that the count starts from 1, every 2 numbers are calculated, until the integer closest to 10 is listed, that is, 1 bathome 3, 5, 5, 7, 9, and then the next is 11, more than 10, is no longer counted, so the statement after do is only executed 5 times, will be displayed 5 bathome in a row.
In fact, the values of xQuery y and z can be positive or negative, or even zero, and the restrictions are very loose:
1. The value of step y cannot be 0.
2. When the value of step y is a positive integer, the termination value z cannot be less than the initial value x.
3. When the value of step y is a negative integer, the termination value z cannot be greater than the initial value x.
In other words, you must ensure that a valid array sequence can be fetched between in and do.
For example:
For / l% I in (- 1mem2myr5) do echo bathomefor / l% I in (5mae2mai 1) do echo bathome
The function of the above two codes is exactly the same, showing bathome 4 times, except that [code26] is calculated in positive order, while [code27] is counted in reverse order.
The following lines of code are problematic:
For / l% I in (1mem0Magne1) do echo bathomefor / l% I in (2mae1Magol 1) do echo bathomefor / l% I in (1mai Laimei 1mai 2) do echo bathome
Among them, [code28] violates the limit that the step size cannot be zero and will fall into an infinite loop; [code29] and [code30] both make the same mistake: unable to get a valid sequence element, resulting in an empty element between in and do, thus making the entire for statement impossible to execute.
When you understand the specific functions of for / l, will you think of goto loop statements that are similar to it? It seems that for / l and goto loop statements can be replaced with each other.
In general, for / l statements can be replaced with goto loops, but goto loops are not necessarily replaced by for / l statements. Please think about the specific reasons. I will not explain them in detail here, but I will only provide a concise answer to a question that you are very concerned about, that is, when to use for / l to count loops and when to use goto conditional loops?
The answer is very simple: when the number of loops is determined, the for / l statement is preferred, or the Goto statement is not recommended; when the number of loops is uncertain, the Goto statement will be the only choice, because conditional statements such as if need to be used to determine when to end the goto jump.
The above is all the content of this article "for sentence use example Analysis". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
We will make a page that can remember the names of the visitors, here
© 2024 shulou.com SLNews company. All rights reserved.