IFS in the shell

Source: Internet
Author: User

I. Introduction of IFS

The Shell script has a variable called IFS (Internal field Seprator), the internal domain delimiter. The full definition is the shell uses the value stored in IFS, which are 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 performing variable substitution.

Shell environment variables are set, env two, where set variables can be imported into the env variable through the export tool. Where set is the display set shell variable, only valid in this shell; Env is a display set user environment variable, valid only in the current session. In other words, the SET variable contains the ENV variable, but the set variable is not necessarily an env variable. The difference between the two variables is that the scope of the variable is different. Obviously, the scope of the env variable is larger, and it can be used in Subshell.

IFS is a set variable, and when the shell handles "command substitution" and "parameter substitution", the shell, by default, is space, tab, newline to break into variables, and then process the special characters, and finally regroup the variables, based on the IFS value.

Ii. Simple examples of IFS

1. View the value of the variable IFS.

[Plain]View PlainCopy
    1. $ echo $IFS
    2. $ echo "$IFS" | Od-b
    3. 0000000 040 011) 012 012
    4. 0000004

Direct output IFS is not visible, convert it to binary can be seen, "040" is a space, "011" is the tab, "012" is the newline character "\ n". The last 012 is because echo defaults to wrap.

2, $* and [e-mail protected] subtle differences
As can be seen from the following example, if it is caused by a colon, it means that the variable is not replaced with IFS!! So you can see the "original value" of this variable. Conversely, if you do not quote, the output will be based on the value of IFS to split after the combined output! $* is determined by the first value in the IFS! Here are two examples with subtle differences!

[Plain]View PlainCopy
    1. $ ifs=:;
    2. $ set X y Z
    3. $ echo $*
    4. X y Z
    5. $ echo "$*"
    6. X:y:z
    7. $ echo [email protected]
    8. X y Z
    9. $ echo "[email protected]"
    10. X y Z

The above example set variable is actually 3 parameters, and the following example is essentially 2 parameters, that is, set "x y z" and set X y z are completely different.

[Plain]View PlainCopy
    1. $ set "x" "Y z"
    2. $ echo $*
    3. X y Z
    4. $ echo "$*"
    5. X:y Z
    6. $ echo [email protected]
    7. X y Z
    8. $ echo "[email protected]"
    9. X y Z
    10. $ echo $* |od-b
    11. 0000000 170 040 171 040 172 012
    12. 0000006
    13. $ echo "$*" |od-b
    14. 0000000 170 072 171 040 172 012
    15. 0000006

Summary: $* will combine values based on IFS, while [email protected] will combine values with ""!

3. Strange phenomenon in for loop

[Plain]View PlainCopy
    1. $ for x in $var;d o echo $x |od-b;d One
    2. 0000000 012
    3. 0000001
    4. 0000000 040 141 012
    5. 0000003
    6. 0000000 142 012
    7. 0000002
    8. 0000000 012
    9. 0000001
    10. 0000000 143 012
    11. 0000002

Let's not explain for the contents of the For loop! Look at the output below! IFS values as above! Var= ": a:b::c:",

[Plain]View PlainCopy
    1. $ echo $var |od-b
    2. 0000000 040 040 141 040 142 040 040 143 012
    3. 0000011
    4. $ echo "$var" |od-b
    5. 0000000 072 040 141 072 142 072 072 143 072 012
    6. 0000012

The value of "$var" should not be replaced, so it is still ": A:b::c:" (note "072" for the colon), but $var has changed! Note that the last colon of the output is not, and is not replaced by a space! Why?

Using $var is a process that has gone through! First, follow such rules [variable][ifs][variable][ifs] ... The variable is divided according to all the delimiters (":") in the original Var value, if the value of IFS is composed of multiple characters, such as ifs= ":;", then [IFS] here refers to any one of the characters in the IFS ($* is delimited by the first character !). ), such as ":" or ";", followed by the [IFS] do not do similar instructions! (Note: [IFS] will have multiple values, thanks to #blackold reminders); Then, get a list like this, "" a "" B "" "" C ". If Echo $var at this point, you need to separate the variables with a space, which means "[space]" a "[space]" B "[space]" [space] "C", ignoring the null value, and the final output is [space][space]a[ Space]b[space][space]c!

If the last character is not a delimiter, such as var= "A:B", then the last delimiter is the last variable!

Take care of this place!! If IFS is a space, then similar to "[Space][space]a[space]b[space][space]c" will merge the repeating part, and go to the head space, the trailing space, then the final output will become similar to A[space]b[space]c, so, If IFS is the default value, then the result of processing is very good to calculate, directly merge, ignore extra space!

In addition, $* and [email protected] in the function of the process is such (only consider "original value"!) )! "[Email protected]", is like above processing after assignment, but "$*" but not the same! Its value is separated by a delimiter (such as ":") instead of a space! See the last example for a specific example!

OK, now to explain the contents of the For loop. The For loop iterates through the above list, so the first output for the For loop is empty! ("012" is the line break for echo Output) .... Back, and so on! Do not believe can try the following example, the result is the same!

[Plain]View PlainCopy
    1. $ for X in "" "A" "B" "" "C";d o echo $x |od-b;d One
    2. 0000000 012
    3. 0000001
    4. 0000000 040 141 012
    5. 0000003
    6. 0000000 012
    7. 0000001
    8. 0000000 142 012
    9. 0000002
    10. 0000000 012
    11. 0000001
    12. 0000000 143 012
    13. 0000002

Iii. Other examples of IFS

Example 1:

[Plain]View PlainCopy
    1. $ ifs=:
    2. $ var=ab::cd
    3. $ echo $var
    4. AB CD
    5. $ echo "$var"
    6. Ab::cd

Explanation: The value of x is "AB::CD", and the variable substitution occurs when the echo $x is made because of the $ character. The Shell breaks x into AB "" CDs based on the value of IFS, then echoes, inserts an empty compartment, ab[space] "" [Space]cd, ignores "", Outputs AB CD .

Example 2:

[Plain]View PlainCopy
    1. $ read a
    2. XY Z
    3. $ echo $a
    4. XY Z

Explanation: This is an example on the http://bbs.chinaunix.net/thread-207178-1-1.html. At this point IFS is the default value, I would like to put all the input (including spaces) into the variable a, but the output of a but the front of the space to ignore it!! The reason: The default IFS is split by Space tab newline. One thing to note here is the implementation of the Read command, which was replaced when it was read. The solution is to add a ifs= ";" to the beginning, which must be enclosed in double quotes, because the semicolon has a special meaning.

Example 3:

[Plain]View PlainCopy
    1. $ tmp= "XY z"
    2. $ a= $tmp
    3. $ echo $a
    4. $ echo "$a"

Explanation: When will it be "processed" according to IFS? I think that, for non-quoted variables, you will refer to IFS when used, but be careful with the original values!

Example 4:

[Plain]View PlainCopy
    1. #!/bin/bash
    2. ifs_old= $IFS #将原IFS值保存 in order to recover after use
    3. ifs=$ ' \ n ' #更改IFS值为 $ ' \ n ', note that to enter as a delimiter, IFS must be: $ ' \ n '
    4. For I in $ ((cat pwd.txt)) #pwd. txt from this command: CAT/ETC/PASSWD >pwd.txt
    5. Do
    6. Echo $i
    7. Done
    8. ifs= $IFS _old #恢复原IFS值

Another example is to reverse the output of an IP address:

Example 5:

[Plain]View PlainCopy
    1. #!/bin/bash
    2. ip=220.112.253.111
    3. Ifs= "."
    4. tmpip=$ (Echo $IP)
    5. Ifs= "" # Space
    6. Echo $TMPIP
    7. For x in $TMPIP;d o
    8. Xip= "${x}. $Xip"
    9. Done
    10. Echo ${xip%.}

Complex_example 1:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3660898&page=1#pid21798049

[Plain]View PlainCopy
    1. function Output_args_ifs () {
    2. echo "=$*"
    3. echo "=" $*
    4. For M in $*;d o
    5. echo "[$m]"
    6. Done
    7. }
    8. Ifs= ': '
    9. Var= ':: a:b::c::: '
    10. Output_args_ifs $var

The output is:

[Plain]View PlainCopy
    1. =::A:B::C:: # The last colon is missing! Look ahead, you know why.
    2. = a b C
    3. []
    4. []
    5. A
    6. [b]
    7. []
    8. C
    9. []

Because $var in "output_args_ifs $var" are not quoted, they are replaced by IFS! The variables are divided according to IFS: "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " ), the result of the reorganization is

"[Email protected]" value is "[Space]" "[Space]" a "[space]" B "[space]" [space] "C" [space] "[space]" ", can pass, echo= = "A b C"
The value of "$*" is "[IFS]" "[IFS]" a "[IFS]" B "[IFS]" [IFS] "C" [IFS] "[IFS]" ", Ignoring",echo=> ":: A:b::c::"

Note that the values for $* and [email protected] are "" "" "" "A" "B" "" "C" "" ". Can be said to be a list ... Because they're supposed to be $ ... Composed of.

Therefore, the "Linux programming" recommended the use of [email protected], rather than $*

Summary: IFS is still very troublesome, a little careless will produce very strange results, so use the time to pay attention! I have also gone a lot of detours, just hope to give some help to the later people. If there is a problem in this article, please correct me!! Thank you!

If there is reprint, please specify Blog.csdn.net/whuslei
Reference:
http://blog.chinaunix.net/space.php?uid=20543672&do=blog&id=94358
http://smilejay.com/2011/12/bash_ifs/#comment-51

IFS in the shell

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.