### A Little Discussion on Batch Processing Parameter Issues
Recently, I wrote a batch processing program and wanted the program to flexibly receive up to two parameters. However, I encountered difficulties during the process, such as how to handle different numbers of parameters and how to realize the judgment of parameter types. After some time of thinking and exploration, I finally solved these problems satisfactorily. Next, I will talk about this process. If you want to test the effect, please do it under the NT system.
First, let's explain the parameters that this batch processing program is supposed to receive. One parameter is a path, and the other is a number. Then there are the following several combination transformations:
1. Empty
2. Path
3. Number
4. Path + Number
5. Number + Path
6. Path + Path
7. Number + Number
The first five cases are the normal parameter combinations that the program needs to handle, and the latter two are the unexpected combinations. Let's first look at the following demo program and discuss the processing and implementation of this process together.
In the first six lines, flag_n and flag_d are two variables to record the number of numbers and directories in the parameters respectively and will be used later, and the rest will not be explained too much. Focus on lines 7 to 17. This is an if...else... branch structure. The first branch is further divided into two parts. The two variables p1 and p2 respectively record the parameter 1 and parameter 2 received by demo.cmd, so the entire part is divided into three situations that can be described by the number of parameters, namely no parameters, one parameter, and two parameters. Let's see what operations are performed in each branch situation respectively.
First, let's talk about the situation of no parameters in line 9. The statement means assigning the variable directory the value ".". It is necessary to explain this statement in detail. Since no parameters are input to demo.cmd, why set the variable directory? The purpose of this is to set a default value for the directory variable. In subsequent calls, such as dir %directory%; for /r "%directory%" in (*.*) do .... In such commands, even if demo.cmd does not receive the path parameter, there will be no error because there is this default ".", that is, it represents the current directory in the default state. Of course, whether it is necessary to do this in this way depends on how you use the directory variable in subsequent commands. Since the above code is just a demonstration of parameter reception, there are no subsequent related operations. If you don't need to design the directory to be empty, you can replace lines 8-10 with "if defined p1 (" to simplify it and only keep the next branch.
Next, let's talk about the next branch mentioned above, that is, the else part of the second if statement, that is, the situation of one parameter. Because the content of this one parameter will still be either a path or a number, it is necessary to assign the variable directory the value ".", just in case the parameter encountered is a number, that is, the function of line 11. Then look at line 12, which jumps to the label _test with p1 as the parameter to complete a call similar to a function. We don't know what function is completed, so let's put it aside and look down. Then comes the else part of the first if statement, that is, the situation of two parameters. It is found that the _test function is called twice with p1 and p2 respectively. Now we need to study what function the _test function actually completes.
Directly jump to line 23. First, the statement assigns the parameter sent above to the variable x. Then, an arithmetic operation is performed to assign the value to the variable y, adding 1 first and then subtracting 1, which is a bit confusing. Then, look at the first branch of the if statement. If the values of x and y are equal, assign the value of x to the variable number and add 1 to flag_n. We still remember that flag_n is the variable to record the number of numbers in the parameters. It seems that if the values of x and y are equal, it is determined that x, that is, the parameter sent above, is a number. Why is this? Line 25 should be the key. Here is a small trick. First, insert a set help:
"In any non-numeric string in the expression is treated as an environment variable name, and the value of these environment variable names is converted to a number before use. If an environment variable name is specified but not defined in the current environment, then the value will be set to zero. This allows you to use environment variable values for calculations without having to type those % symbols to get their values."
Now it is clear the execution process of the sentence set /a "y=x+1-1". The x is replaced by its own variable value to participate in the operation. When the x value is a number, adding 1 first and then subtracting 1 leaves its value unchanged, that is, y = x; when the x value is a non-number, its value will be set to zero, and after adding 1 first and then subtracting 1, y = 0. So based on this, it can also be judged whether the x value is a number. A careful person will guess what if x itself is 0. This is a special case. You can judge before the set /a sentence and change the program execution order to complete the specified operation. However, this processing method of directly participating the variable in numerical operation also has limitations. For example, the x value 0123 will be judged as a non-number, because the number starting with 0 will be interpreted as an octal number with a value of 83. So the natural numbers that we can correctly judge are only natural numbers. Is there a way to avoid or solve this problem? We will talk about this problem later.
Next, let's look at the else branch of the if statement in the _test function. Line 30 pushd "%x%" will save the current directory for subsequent commands to use the popd command, and switch to the directory represented by x. Simply put, it saves the current directory and changes the directory. The next line decides the program's turn according to the execution situation of the pushd command. If it is wrong, that is, the non-directory situation, it still sets directory to "." and exits the function. Lines 32-34 are very simple. If pushd is executed successfully, set directory to the value of x, increment flag_d by 1, and then switch to the saved directory. In this way, the judgment of whether it is a directory is completed. Let's see that we have ignored the error input situation of non-number and non-directory. This is just to better understand this process and is ignored. You can set a flag_o variable at the beginning and add set /a flag_o+=1 in the if errorlevel 1 sentence to record this situation. Of course, for the convenience of understanding and description, I used the connection符 "&" for executing multiple commands in parallel; actually, you can use parentheses to enclose multiple statement segments to execute them respectively.
In this way, we have realized the judgment of numbers, directories and other characters. Then it is easy to understand when returning to the main program, just display the information we saved, and in practical applications, it will be used for other commands. Think about what omissions we have. For example, what if one parameter 456 is a directory? We can add a judgment of whether it is a directory before line 27? And what if there is a directory 456 but it is a number we want? This is an unanswerable question. So the best way to avoid such ambiguous situations is to require entering the full path, which is the word mentioned at the beginning of the article, instead of the word directory we have been using in the middle of the article. Let's talk about the problem of numbers starting with zero. Since the required is the full path, numbers starting with zero must not be directories. We can use the substring extraction command to loop and replace the preceding zeros and then make a judgment. In fact, is it necessary for us to do this? I can't say no, that depends on the degree of fault tolerance you require for the program.
Looking back at this way of parameter processing, we will find that it is difficult to cope with the complex situation of multiple parameters. A better way should be the receiving and processing mode like demo /A... /B... /C..., using options to limit the parameters. The advantage of this is that you just need to receive according to the qualifier, instead of leaving the unordered parameters to the batch processing program for analysis and judgment. This is just an initial idea and I don't know whether it can be converted into a feasible and practical batch processing program. Friends are welcome to discuss together.
Postscript: Originally, I just wanted to record the problems I encountered here, but I didn't expect to be so wordy. If there are any omissions, I hope to be corrected.
Recently, I wrote a batch processing program and wanted the program to flexibly receive up to two parameters. However, I encountered difficulties during the process, such as how to handle different numbers of parameters and how to realize the judgment of parameter types. After some time of thinking and exploration, I finally solved these problems satisfactorily. Next, I will talk about this process. If you want to test the effect, please do it under the NT system.
First, let's explain the parameters that this batch processing program is supposed to receive. One parameter is a path, and the other is a number. Then there are the following several combination transformations:
1. Empty
2. Path
3. Number
4. Path + Number
5. Number + Path
6. Path + Path
7. Number + Number
The first five cases are the normal parameter combinations that the program needs to handle, and the latter two are the unexpected combinations. Let's first look at the following demo program and discuss the processing and implementation of this process together.
:: demo.cmd Demonstration of Batch Processing Parameter Handling ↑ for 2000, XP
:: by: Wuna ihe email: wunaihe@gmail.com 2005.11.17
1│@echo off
2│setlocal
3│set "p1=%~1"
4│set "p2=%~2"
5│set flag_d=0
6│set flag_n=0
7│if not defined p2 (
8│ if not defined p1 (
9│ set "directory=."
10│ ) else (
11│ set "directory=."
12│ call :_test "%p1%"
13│ )
14│) else (
15│ call :_test "%p1%"
16│ call :_test "%p2%"
17│ )
18│if %flag_n% == 2 echo The parameters are two numbers &goto :EOF
19│if %flag_d% == 2 echo The parameters are two directories &goto :EOF
20│echo The directory is: %directory% The number is: %number%
21│goto :EOF
22│
23│:_test
24│set "x=%~1"
25│set /a "y=x+1-1"
26│if "%y%" == "%x%" (
27│ set "number=%x%"
28│ set /a flag_n+=1
29│ ) else (
30│ pushd "%x%" 2>nul
31│ if errorlevel 1 set "directory=." &goto :EOF
32│ set "directory=%x%"
33│ set /a flag_d+=1
34│ popd
35│ )
36│goto :EOF
In the first six lines, flag_n and flag_d are two variables to record the number of numbers and directories in the parameters respectively and will be used later, and the rest will not be explained too much. Focus on lines 7 to 17. This is an if...else... branch structure. The first branch is further divided into two parts. The two variables p1 and p2 respectively record the parameter 1 and parameter 2 received by demo.cmd, so the entire part is divided into three situations that can be described by the number of parameters, namely no parameters, one parameter, and two parameters. Let's see what operations are performed in each branch situation respectively.
First, let's talk about the situation of no parameters in line 9. The statement means assigning the variable directory the value ".". It is necessary to explain this statement in detail. Since no parameters are input to demo.cmd, why set the variable directory? The purpose of this is to set a default value for the directory variable. In subsequent calls, such as dir %directory%; for /r "%directory%" in (*.*) do .... In such commands, even if demo.cmd does not receive the path parameter, there will be no error because there is this default ".", that is, it represents the current directory in the default state. Of course, whether it is necessary to do this in this way depends on how you use the directory variable in subsequent commands. Since the above code is just a demonstration of parameter reception, there are no subsequent related operations. If you don't need to design the directory to be empty, you can replace lines 8-10 with "if defined p1 (" to simplify it and only keep the next branch.
Next, let's talk about the next branch mentioned above, that is, the else part of the second if statement, that is, the situation of one parameter. Because the content of this one parameter will still be either a path or a number, it is necessary to assign the variable directory the value ".", just in case the parameter encountered is a number, that is, the function of line 11. Then look at line 12, which jumps to the label _test with p1 as the parameter to complete a call similar to a function. We don't know what function is completed, so let's put it aside and look down. Then comes the else part of the first if statement, that is, the situation of two parameters. It is found that the _test function is called twice with p1 and p2 respectively. Now we need to study what function the _test function actually completes.
Directly jump to line 23. First, the statement assigns the parameter sent above to the variable x. Then, an arithmetic operation is performed to assign the value to the variable y, adding 1 first and then subtracting 1, which is a bit confusing. Then, look at the first branch of the if statement. If the values of x and y are equal, assign the value of x to the variable number and add 1 to flag_n. We still remember that flag_n is the variable to record the number of numbers in the parameters. It seems that if the values of x and y are equal, it is determined that x, that is, the parameter sent above, is a number. Why is this? Line 25 should be the key. Here is a small trick. First, insert a set help:
"In any non-numeric string in the expression is treated as an environment variable name, and the value of these environment variable names is converted to a number before use. If an environment variable name is specified but not defined in the current environment, then the value will be set to zero. This allows you to use environment variable values for calculations without having to type those % symbols to get their values."
Now it is clear the execution process of the sentence set /a "y=x+1-1". The x is replaced by its own variable value to participate in the operation. When the x value is a number, adding 1 first and then subtracting 1 leaves its value unchanged, that is, y = x; when the x value is a non-number, its value will be set to zero, and after adding 1 first and then subtracting 1, y = 0. So based on this, it can also be judged whether the x value is a number. A careful person will guess what if x itself is 0. This is a special case. You can judge before the set /a sentence and change the program execution order to complete the specified operation. However, this processing method of directly participating the variable in numerical operation also has limitations. For example, the x value 0123 will be judged as a non-number, because the number starting with 0 will be interpreted as an octal number with a value of 83. So the natural numbers that we can correctly judge are only natural numbers. Is there a way to avoid or solve this problem? We will talk about this problem later.
Next, let's look at the else branch of the if statement in the _test function. Line 30 pushd "%x%" will save the current directory for subsequent commands to use the popd command, and switch to the directory represented by x. Simply put, it saves the current directory and changes the directory. The next line decides the program's turn according to the execution situation of the pushd command. If it is wrong, that is, the non-directory situation, it still sets directory to "." and exits the function. Lines 32-34 are very simple. If pushd is executed successfully, set directory to the value of x, increment flag_d by 1, and then switch to the saved directory. In this way, the judgment of whether it is a directory is completed. Let's see that we have ignored the error input situation of non-number and non-directory. This is just to better understand this process and is ignored. You can set a flag_o variable at the beginning and add set /a flag_o+=1 in the if errorlevel 1 sentence to record this situation. Of course, for the convenience of understanding and description, I used the connection符 "&" for executing multiple commands in parallel; actually, you can use parentheses to enclose multiple statement segments to execute them respectively.
In this way, we have realized the judgment of numbers, directories and other characters. Then it is easy to understand when returning to the main program, just display the information we saved, and in practical applications, it will be used for other commands. Think about what omissions we have. For example, what if one parameter 456 is a directory? We can add a judgment of whether it is a directory before line 27? And what if there is a directory 456 but it is a number we want? This is an unanswerable question. So the best way to avoid such ambiguous situations is to require entering the full path, which is the word mentioned at the beginning of the article, instead of the word directory we have been using in the middle of the article. Let's talk about the problem of numbers starting with zero. Since the required is the full path, numbers starting with zero must not be directories. We can use the substring extraction command to loop and replace the preceding zeros and then make a judgment. In fact, is it necessary for us to do this? I can't say no, that depends on the degree of fault tolerance you require for the program.
Looking back at this way of parameter processing, we will find that it is difficult to cope with the complex situation of multiple parameters. A better way should be the receiving and processing mode like demo /A... /B... /C..., using options to limit the parameters. The advantage of this is that you just need to receive according to the qualifier, instead of leaving the unordered parameters to the batch processing program for analysis and judgment. This is just an initial idea and I don't know whether it can be converted into a feasible and practical batch processing program. Friends are welcome to discuss together.
Postscript: Originally, I just wanted to record the problems I encountered here, but I didn't expect to be so wordy. If there are any omissions, I hope to be corrected.
Recent Ratings for This Post
( 1 in total)
Click for details
| Rater | Score | Time |
|---|---|---|
| huanbei | +1 | 2008-11-06 21:24 |

DigestI
arseLoop