ubuntu:bash:the_ifs_internal_field_separator
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
ubuntu:bash:the_ifs_internal_field_separator [2019/12/07 00:04] – peter | ubuntu:bash:the_ifs_internal_field_separator [2019/12/07 00:11] (current) – removed peter | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Ubuntu - BASH - The IFS (internal field separator) ====== | ||
- | The IFS variable is used in shells (Bourne, POSIX, ksh, bash) as the input field separator (or internal field separator). | ||
- | |||
- | Essentially, | ||
- | |||
- | The default value of IFS is space, tab, newline. | ||
- | |||
- | If IFS is unset, it acts as though it were set to this default value. | ||
- | |||
- | If IFS is set to an empty string (which is very different from unsetting it!) then no splitting will be performed. | ||
- | |||
- | |||
- | |||
- | This variable is used in a few different places. The semantics vary slightly: | ||
- | |||
- | * In the **read** command, if multiple variable-name arguments are specified, IFS is used to split the line of input so that each variable gets a single field of the input. | ||
- | |||
- | * When performing WordSplitting on an unquoted expansion, IFS is used to split the value of the expansion into multiple words. | ||
- | |||
- | * When performing the " | ||
- | |||
- | * Likewise, when doing " | ||
- | |||
- | * IFS is used by complete -W under programmable completion. | ||
- | |||
- | ---- | ||
- | |||
- | ===== Whitespace characters in IFS ===== | ||
- | |||
- | There are special rules for handling whitespace characters in IFS, in any of the field-splitting situations above (the first two bullet points). | ||
- | |||
- | Whitespace IFS characters at the beginning and end of a string are removed entirely, and consecutive whitespace IFS characters inside a string are treated as a single delimiter. | ||
- | |||
- | For example, consider the following: | ||
- | |||
- | <code bash> | ||
- | IFS=: read user pwhash uid gid gecos home shell \ | ||
- | <<< | ||
- | </ | ||
- | |||
- | In this example, the gecos variable is assigned the empty string, which is the contents of the field between the two adjacent colons. | ||
- | |||
- | The colons are not consolidated together; they are treated as separate delimiters. | ||
- | |||
- | ---- | ||
- | |||
- | Another example: | ||
- | |||
- | <code bash> | ||
- | IFS=$' \t\n' read one two three \ | ||
- | <<< | ||
- | </ | ||
- | |||
- | In the second example, the one variable gets the value 1, and the two variable gets the value 2. | ||
- | |||
- | The leading whitespace is trimmed, and the internal whitespace is consolidated. | ||
- | |||
- | ---- | ||
- | |||
- | ===== More random examples ===== | ||
- | |||
- | <code bash> | ||
- | IFS= read a b c <<< | ||
- | echo " | ||
- | =the plain gold ring= | ||
- | |||
- | $ IFS=$' \t\n' read a b c <<< | ||
- | $ echo " | ||
- | =gold ring= | ||
- | |||
- | $ IFS=$' \t\n' read a b c <<< | ||
- | $ echo "=$a= =$b= =$c=" | ||
- | =the= =plain= =gold ring= | ||
- | </ | ||
- | |||
- | The first example above shows the lack of splitting when IFS is empty. | ||
- | |||
- | The second shows the last variable-name given to a read command absorbing all the remaining words of input. | ||
- | |||
- | The third shows that splitting and delimiter-consolidation are not performed on the remaining part of a line when assigning excess fields to the last variable. | ||
- | |||
- | ---- | ||
- | |||
- | ===== Having more input fields than variables ===== | ||
- | |||
- | <code bash> | ||
- | $ IFS=: read a b c <<< | ||
- | $ echo "=$a= =$b= =$c=" | ||
- | =1= =2= =::3::4= | ||
- | </ | ||
- | |||
- | Note that out of the three consecutive colons which follow field 2, precisely one colon was removed in order to terminate field 2. | ||
- | |||
- | The remaining two colons, as well as two more colons later on, were all left untouched, and assigned to variable c verbatim. | ||
- | |||
- | ---- | ||
- | |||
- | ===== Iterate through the colon-separated elements of the PATH variable ===== | ||
- | |||
- | This example iterates through the colon-separated elements of the PATH variable, presumably to look for a command. | ||
- | |||
- | <code bash> | ||
- | IFS=: | ||
- | set -f | ||
- | for dir in $PATH; do | ||
- | ... | ||
- | done | ||
- | set +f | ||
- | unset IFS | ||
- | </ | ||
- | |||
- | It is an overly-simplified example, but should serve to demonstrate how IFS may be used to control WordSplitting. | ||
- | |||
- | For a better approach to finding commands, see FAQ #81. | ||
- | |||
- | ---- | ||
- | |||
- | ===== Special note ===== | ||
- | |||
- | Regarding the behavior of $* vs. " | ||
- | |||
- | <code bash> | ||
- | set -- one two three | ||
- | IFS=+ | ||
- | echo $* | ||
- | one two three | ||
- | </ | ||
- | |||
- | What's actually happening here? | ||
- | |||
- | At first glance, it appears $* is generating a list of words without any delimiter, and relying on the echo to put a space between them. | ||
- | |||
- | But that's not the case. $* is generating a single string with our IFS delimiter between elements, but then because it's not quoted, it is split into words before echo gets it. | ||
- | |||
- | ---- | ||
- | |||
- | ===== Variable assignment ===== | ||
- | |||
- | <code bash> | ||
- | tmp=$* | ||
- | echo " | ||
- | one+two+three | ||
- | </ | ||
- | |||
- | Variable assignment skips word splitting (because there' | ||
- | |||
- | By definition, the delimiter we're putting between the words will be part of IFS, and therefore it will be word-split away. There' | ||
- | |||
- | This is yet another reason why you should USE MORE QUOTES! |
ubuntu/bash/the_ifs_internal_field_separator.1575677041.txt.gz · Last modified: 2020/07/15 09:30 (external edit)