1. Introduction to IFS
The shell script has an internal domain separator called ifs (internal field seprator. The complete definition is the shell uses the value stored in IFS, which is the space, tab, and newline characters by default, to delimit words for the read and set commands, when parsing output from command substitution, and when implements Ming variable substitution.
Shell environment variables include set and env. The set variables can be imported to the Env variables through the export tool. Set is the display setting shell variable, which is only valid in this shell; ENV is the display setting user environment variable, which is only valid in the current session. In other words, the set variable contains the env variable, but the set variable is not always the env variable. The two variables have different scopes. Obviously, the env variable has a larger scope and can be used in subshell.
IFS is a set variable. When the shell processes "command Replace" and "parameter Replace", the shell uses the space, tab, newline is used to disassemble the read variables, process special characters, and re-combine and assign values to the variables.
Ii. Simple ifs instance
1,View the value of the variable IFS.
[Plain]View plaincopyprint?
- $ Echo $ IFS
- $ Echo "$ ifs" | OD-B
- 0000000 040 011 012 012
- 0000004
$ echo $IFS$ echo "$IFS" | od -b0000000 040 011 012 0120000004
Output ifs directly, but convert it to binary. "040" is a space, "011" is a tab, and "012" is a line break "\ n ". The last 012 is because ECHO will wrap by default.
2,Nuances between $ * and [email protected]
As shown in the following example, if it is caused by a colon, this variable does not need to be replaced by ifs !! So we can see the "original value" of this variable ". Otherwise, if no quotation marks are added, the output will be split Based on the IFS value and then merged into the output! $ * Is determined based on the first value in IFS! The two examples below are slightly different!
[Plain]View plaincopyprint?
- $ Ifs = :;
- $ Set X Y Z
- $ Echo $ *
- X Y Z
- $ Echo "$ *"
- X: Y: Z
- $ Echo [email protected]
- X Y Z
- $ Echo "[email protected]"
- X Y Z
$ IFS=:;$ set x y z$ echo $*x y z$ echo "$*"x:y:z$ echo [email protected]x y z$ echo "[email protected]"x y z
In the above example, the set variable is actually three parameters, and the following example is actually two parameters, that is, set "x y z" and set x y z are completely different.
[Plain]View plaincopyprint?
- $ Set "X" "y z"
- $ Echo $ *
- X Y Z
- $ Echo "$ *"
- X: Y Z
- $ Echo [email protected]
- X Y Z
- $ Echo "[email protected]"
- X Y Z
- $ Echo $ * | OD-B
- 0000000 170 040 171 040 172 012
- 0000006
- $ Echo "$ *" | OD-B
- 0000000 170 072 171 040 172 012
- 0000006
$ set "x" "y z"$ echo $*x y z$ echo "$*"x:y z$ echo [email protected]x y z$ echo "[email protected]"x y z$ echo $* |od -b0000000 170 040 171 040 172 0120000006$ echo "$*" |od -b0000000 170 072 171 040 172 0120000006
Summary: $ * combines values based on IFS, while [email protected] combines values!
3,Strange Phenomena in the For Loop
[Plain]View plaincopyprint?
- $ For X in $ var; do echo $ X | OD-B; done
- 0000000 012
- 0000001
- 0000000 040 141 012
- 0000003
- 0000000 142 012
- 0000002
- 0000000 012
- 0000001
- 0000000 143 012
- 0000002
$ for x in $var ;do echo $x |od -b ;done0000000 01200000010000000 040 141 01200000030000000 142 01200000020000000 01200000010000000 143 0120000002
The content of the For Loop is not explained for the moment! See the output below! The value of IFS is the same as that of IFS!Var = ": A: B: C :",
[Plain]View plaincopyprint?
- $ Echo $ var | OD-B
- 0000000 040 040 141 040 142 040 040 143 012
- 0000011
- $ Echo "$ Var" | OD-B
- 0000000 072 040 141 072 142 072 072 143 072 012
- 0000012
$ echo $var |od -b0000000 040 040 141 040 142 040 040 143 0120000011$ echo "$var" |od -b0000000 072 040 141 072 142 072 072 143 072 0120000012
The value of "$ Var" should not be replaced, so ": A: B: C:" (note "072" indicates a colon), but $ VaR is changed! Note that the last colon in the output is absent and is not replaced with a space! Why?
Use $ VaRThis is a process! First, follow these rules [variables] [ifs] [variables] [ifs]… The variable is divided based on all the delimiters (":") in the original VaR value. If the IFS value is composed of multiple characters, such as IFs = ":;", the [ifs] here refers toAny character($ * Is to pressFirst characterTo separate !), For example, ":" or ";",[Ifs]! (Note: [ifs] has multiple values, thanks to the # blackold Reminder). Then, get a list like this, "A" C ". IfEcho $ VaRAre separated by spaces, that is, "" [space] "A" [space] "B" [space] "" [space] "C ",Ignore null valuesAnd the final output is [space].[Space][Space]B[Space] [space]C!
If the last character is not a separator, such as Var = "A: B", the variable after the last separator is the last variable!
Pay attention to this place !! If ifs is a space, similar to "[space] [space] a [space] B [space] [space] C", duplicate parts are merged, with leading spaces and trailing spaces removed, the final output will be similar to a [space] B [space] C. Therefore, if ifs is the default value, the processing result will be well calculated. You can directly merge and ignore unnecessary spaces!
In addition, the processing process of $ * and [email protected] In the function is like this (only the "original value" is considered "!)! "[Email protected]" is a value assigned after processing, but "$ *" is different! Its values are separated by delimiters (such as ":") rather than spaces! For more information, see the last example!
Now let's explain the content of the for loop. The for loop can traverse the list above, so the first output of the For Loop is empty! ("012" is the line break output by ECHO ).... And so on! If you don't believe it, try the following example. The result is the same!
[Plain]View plaincopyprint?
- $ For X in "A" "B" C "; do echo $ X | OD-B; done
- 0000000 012
- 0000001
- 0000000 040 141 012
- 0000003
- 0000000 012
- 0000001
- 0000000 142 012
- 0000002
- 0000000 012
- 0000001
- 0000000 143 012
- 0000002
$ for x in "" " a" "b" "" "c" ;do echo $x |od -b ;done0000000 01200000010000000 040 141 01200000030000000 01200000010000000 142 01200000020000000 01200000010000000 143 0120000002
Iii. Other ifs instances
Example 1:
[Plain]View plaincopyprint?
- $ Ifs =:
- $ Var = AB: CD
- $ Echo $ VaR
- AB CD
- $ Echo "$ Var"
- AB: CD
$ IFS=:$ var=ab::cd$ echo $varab cd$ echo "$var"ab::cd
The value of X is "AB: cd". When Echo $ X is performed, the variable is replaced because of the $ character. Shell splits X into AB "" CD according to the IFS value, then ECHO, insert an empty compartment, AB [space] "" [space] cd, ignore "", and output AB CD.
Example 2:
[Plain]View plaincopyprint?
- $ Read
- XY Z
- $ Echo $
- XY Z
$ read a xy z$ echo $axy z
This is an example of a http://bbs.chinaunix.net/thread-207178-1-1.html. In this case, IFS is the default value. I want to put all input (including spaces) into variable A, but output a ignores the leading space !! The reason is that the default IFS will be split by space tab newline. Note that the implementation process of the read command is replaced at the time of reading. The solution is to add an IFS = ";" at the beginning. Double quotation marks must be added here, because the semicolon has a special meaning.
Example 3:
[Plain]View plaincopyprint?
- $ TMP = "xy z"
- $ A = $ TMP
- $ Echo $
- $ Echo "$"
$ tmp=" xy z"$ a=$tmp$ echo $a$ echo "$a"
Explanation: When will it be "processed" based on IFS? I think it is. For variables without quotation marks, you can refer to ifs for use, but pay attention to the original value!
Example 4:
[Plain]View plaincopyprint?
- #! /Bin/bash
- Ifs_old = $ ifs # Save the original ifs value for recovery after use
- Ifs = $ '\ n' # change the IFS value to $' \ n'. Note that if you press enter as the separator, ifs must be: $ '\ n'
- For I in $ (cat pwd.txt) Then pwd.txt comes from this command: CAT/etc/passwd> pwd.txt
- Do
- Echo $ I
- Done
- Ifs = $ ifs_old # restore the original ifs Value
#! /Bin/bashifs_old = $ ifs # Save the original ifs value to restore ifs = $ '\ n' After use # change the IFS value to $' \ n'. Note, use the carriage return as the separator. Ifs must be $ '\ n' for I in $ (cat pwd.txt). Then pwd.txt comes from this command: CAT/etc/passwd> pwd.txt do echo $ idoneifs = $ ifs_old # restore the original ifs Value
In another example, the IP address is reversed:
Example 5:
[Plain]View plaincopyprint?
- #! /Bin/bash
- IP = 220.112.253.111
- Ifs = "."
- Tmpip = $ (echo $ IP)
- Ifs = "" # Space
- Echo $ tmpip
- For X in $ tmpip; do
- Xip = "$ {x}. $ xip"
- Done
- Echo $ {xip % .}
#!/bin/bashIP=220.112.253.111IFS="."TMPIP=$(echo $IP)IFS=" " # spaceecho $TMPIPfor x in $TMPIP ;do Xip="${x}.$Xip"doneecho ${Xip%.}
Complex_example 1:Http://bbs.chinaunix.net/forum.php? MoD = viewthread & tid = 3660898 & page = 1 # pid21798049
[Plain]View plaincopyprint?
- Function output_args_ifs (){
- Echo "= $ *"
- Echo "=" $ *
- For m in $ *; do
- Echo "[$ m]"
- Done
- }
- Ifs = ':'
- Var = ': A: B: C :::'
- Output_args_ifs $ VaR
function output_args_ifs(){ echo "=$*" echo "="$* for m in $* ;do echo "[$m]" done}IFS=‘:‘var=‘::a:b::c:::‘output_args_ifs $var
Output:
[Plain]View plaincopyprint?
- =: A: B: C: # The Last colon is missing! Let's see why.
- = A B C
- []
- []
- [A]
- [B]
- []
- [C]
- []
=: A: B: C: # The Last colon is missing! I can see why = a B c [] [] [a] [B] [] [C] []
Because $ VaR in "output_args_ifs $ Var" is not enclosed by quotation marks, replace it with ifs! The variable "B" C "C" (you can output $ # To test the number of parameters !), The result of the reorganization is
"[Email protected]" is "" [space] "" [space] "A" [space] "B" [space] "" [space] "C "[ space] "" [space] "", echo => "a B C"
The value of "$ *" is "" [ifs] "" [ifs] "A" [ifs] "B" [ifs] "" [ifs] "C" [ifs] "" [ifs] "", ignore "", Echo => ": A: B: C ::"
Note that the values of $ * and [email protected] are "A" "B" C """"". A list ...... Because they were originally created from $1 $2 $3 ...... .
Therefore, [email protected] is recommended in Linux programming, instead of $ *
Http://blog.csdn.net/whuslei/article/details/7187639