Lecture
This is the last lecture dedicated to learning bash . Today we will talk about working with strings, as well as discuss bash commands and constructions that were missed in previous lectures. First, consider one of these important constructions, and then proceed to the processing of strings.
In many system scripts, you can see a post like this:
one | . / lib / lsb / init-functions |
This is the point after which the space followed by the path to the file. Do not confuse this with the option without a space - ./lib/lsb/init-functions . A dot with a space after which follows the path to the text file allows you to load the text of this file into the current script. This mechanism can be compared with the *** *** include in the C language. This mechanism has a great practical application. For example, you can describe frequently used *** functions in a separate file, and then use functions in other scripts. The same mechanism is used to create configuration files. Consider a practical example. Create a file called testopt with the following content:
one 2 3 four | # Configuration file # Set the display option: PRINT = YES PRINT2 = NO |
Then create another script file named printopt.sh in the same directory as the testopt file:
one 2 3 four | #! / bin / bash . testopt if [$ PRINT = "YES"]; then echo "PRINT"; fi if [$ PRINT2 = "YES"]; then echo "PRINT2"; fi |
When the bash interpreter starts to parse the printopt.sh script at startup, thanks to the construction . The testopt executable file for the interpreter will look like this:
one 2 3 four five 6 7 | #! / bin / bash # Configuration file # Set the display option: PRINT = YES PRINT2 = NO if [$ PRINT = "YES"]; then echo "PRINT"; fi if [$ PRINT2 = "YES"]; then echo "PRINT2"; fi |
That is, in place . testopt inserts the contents (text) of the testopt file. The result of the script:
one 2 | igor @ ubuntu: ~ / linux $ ./printopt.sh |
Consider a few bash string processing techniques. Suppose there is a variable A , which is assigned the string “ QWERTY “. To display the contents of a variable, just write echo $ A :
one 2 | igor @ ubuntu: ~ / linux $ A = "QWERTY"; echo $ A Qwerty |
Suppose we want to output such a string - QWERTASD . The $ AASD option does not work, since for bash - AASD will be a nonexistent variable:
one | igor @ ubuntu: ~ / linux $ A = "QWERTY"; echo $ AASD |
Therefore, you should write as follows: $ {A} ASD :
one 2 | igor @ ubuntu: ~ / linux $ A = "QWERTY"; echo $ {A} ASD QWERTYASD |
If it is necessary to display a string from the Nth character, then use the $ {A: N} construct, where N is the number of the character from which the string will be displayed. Characters in the line are numbered from scratch. To display ERTY we write:
one 2 | igor @ ubuntu: ~ / linux $ A = "QWERTY"; echo $ {A: 2} ERTY |
In other words, after the colon, we indicate the number of characters to be skipped.
You can display a certain number of characters starting from a certain position. Then you need to write as $ {A: N: M} , where N is the number of the character from which the string will be displayed, and M is the number of displayed characters. To derive the ER characters from our QWERTY line, we write:
one 2 | igor @ adm-ubuntu: ~ $ A = "QWERTY"; echo $ {A: 2: 2} ER |
To output QWE, we write this:
one 2 | igor @ adm-ubuntu: ~ $ A = "QWERTY"; echo $ {A :: 3} QWE |
Consider this construction:
one 2 3 four | igor @ adm-ubuntu: ~ $ A = "ABABABCDCD"; echo $ {A # AB} ABABCDCD igor @ adm-ubuntu: ~ $ A = "123ABABABCDCD"; echo $ {A # AB} 123ABABABCDCD |
After the # symbol, we specify a pattern, and if the beginning of the line matches this pattern, then the string will be output without characters that match the pattern. The line “123ABABABCDCD” starts from 12 and the AB template did not work, but if you write # * AB (or # ??? AB ), then we get the following result:
one 2 3 four | igor @ adm-ubuntu: ~ $ A = "123ABABABCDCD"; echo $ {A # * AB} ABABCDCD igor @ adm-ubuntu: ~ $ A = "123ABABABCDCD"; echo $ {A # ??? AB} ABABCDCD |
Look at the result of this command:
one 2 | igor @ adm-ubuntu: ~ $ A = "123ABABABCDCD"; echo $ {A ## * AB} CDCD |
If we have one character #, then the minimum that satisfies the pattern is separated from the string. That is, for “123ABABABCDCD” is “123AB” . And if we have two ## signs, then the maximum possible part that satisfies the pattern is separated. That is, That is, for “123ABABABCDCD” is “123ABABAB” , since 123ABAB is suitable for * .
If it is necessary to remove characters from the end of the line in the same way, instead of # we use % . The rules are the same as for # .
one 2 3 four | igor @ adm-ubuntu: ~ $ A = "123ABABABCDCD"; echo $ {A% AB *} 123ABAB igor @ adm-ubuntu: ~ $ A = "123ABABABCDCD"; echo $ {A %% AB *} 123 |
Now let's see how bash can replace characters in a string. Suppose you need in our line “123ABABABCDCD” to replace the characters AB with ZX , to make the line “123ZXZXZXCDCD” . For this we use / or // and write so:
one 2 3 four | igor @ adm-ubuntu: ~ $ A = "123ABABABCDCD"; echo $ {A / AB / ZX} 123ZXABABCDCD igor @ adm-ubuntu: ~ $ A = "123ABABABCDCD"; echo $ {A // AB / ZX} 123ZXZXZXCDCD |
Very often in scripts it is necessary to check whether a variable exists, and if it does not exist, create it and assign a specific value. The mechanism described below is used in scripts that read configuration files.
one 2 3 four five 6 | igor @ adm-ubuntu: ~ $ echo $ {options: = "YES"} YES igor @ adm-ubuntu: ~ $ echo $ options YES igor @ adm-ubuntu: ~ $ options = "NO"; echo $ {options: = "YES"} NO |
A com *** y $ {options: = ”YES”} should be understood like this: if the options variable does not exist, then you need to create it and set the value to “YES” , and if the options variable exists, then use its true value. In the command from the last example (line 1), the options variable did not exist, so it was created and assigned the value YES , in the next command (line 3), we see that the options variable was created and assigned the value.
In the following command (line 5), the options variable was created with the value NO (that is, it existed before the echo $ {options: = ”YES”} command) and therefore this value ( NO ) was displayed.
If you need to perform the same operation, but do not assign a value to a variable, then we write instead = , the symbol - :
one 2 3 four | igor @ adm-ubuntu: ~ $ echo $ {options1: - "YES"} YES igor @ adm-ubuntu: ~ $ echo $ options1 . |
That is, if a variable does not exist, then it is not created, and the specified one is used instead of its nonexistent value (in the example, this is “YES” ). This construction works if the variable does not exist or it exists, but with a value of zero length.
If it is necessary, on the contrary, to output some value instead of an existing variable, then the following *** is used: a:
one 2 3 four | igor @ adm-ubuntu: ~ $ options = "NO"; echo $ {options: + "YES"} YES igor @ adm-ubuntu: ~ $ echo $ options NO |
That is, if a variable exists and a value of nonzero length is assigned to it, then output the specified value instead of the variable value, and do not change the variable itself.
For some types of scripts (for example, installation scripts), it is necessary that the user enters any values and they can be used further in the script. To solve this problem in bash there is a com *** and read . In the simplest case, a com *** is written like this: read P1 P2 .... PN , where P1 ... PN are the names of the parameters separated by spaces. A com *** and read reads data from the input stream and writes it into the specified variables. As a separator for the input data, the com *** and read uses the value that is stored in the bash system variable - IFS . Typically, this is a space or tab. Consider an example script:
one 2 3 four five | #! / bin / bash echo "Type your first and last name separated by a space and press Enter:" read P1 P2 echo "Your name: $ P1" echo "Your last name: $ P2" |
And the result of the implementation:
one 2 3 four five | igor @ adm-ubuntu: ~ / linux $ ./hello.sh Type your first and last name separated by a space and press Enter: Igor Kuzmenko Your name: Igor Your last name: Kuzmenko |
If you change the 5th line of the script to echo “Your last name: $ {P2: -“ Last name was missing ”}” , then if you do not enter the last name, the specified value will be substituted:
one 2 3 four five | igor @ adm-ubuntu: ~ / linux $ ./hello.sh Type your first and last name separated by a space and press Enter: Igor Your name: Igor Your last name: Last name was missing |
Com *** and read can be executed with keys. The most significant are:
-n - allows you to specify the number of characters that must be read from the input stream;
-t - allows you to set the number of seconds to wait for data. If the user has not entered anything, after this time the com *** will be completed with an error and the script will be executed further.
-s - disables the display of input information on the console. Used to enter confidential information.
Help on the read command can be obtained from the console using the help read command.
This concludes our encounter with bash . I recommend viewing the scripts from the /etc/init.d/ directory, and now try to understand what each of them executes. So you better understand what happens when you start a service or its completion, and accordingly, when you start and end Linux itself . We certainly did not consider all the teams. I want to remind once again that bash can use both built-in commands and external ones. If you see an unfamiliar com *** u in scripts (take for example the same read ) and there is no help about it with the man read command, it’s probably built in bash com *** and you need to look either in man bash or use help read .
Comments
To leave a comment
LINUX operating system
Terms: LINUX operating system