User Tools

Site Tools


ubuntu:bash:the_ifs_internal_field_separator

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
ubuntu:bash:the_ifs_internal_field_separator [2019/12/06 23:44] peterubuntu: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, it is a string of special characters which are to be treated as delimiters between words/fields when splitting a line of input. 
- 
-The default value of IFS is space, tab, newline.  (A three-character string.) 
- 
-If IFS is unset, it acts as though it were set to this default value.  (This is presumably for simplicity in shells that do not support the $'...' syntax for special characters.) 
- 
-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.  (The last variable gets all the remaining fields, if there are more fields than variables.) 
- 
-  * When performing WordSplitting on an unquoted expansion, IFS is used to split the value of the expansion into multiple words. 
- 
-  * When performing the "$*" or "${array[*]}" expansion (* not @, and quoted -- see below!), the first character of IFS is placed between the elements in order to construct the final output string. 
- 
-  * Likewise, when doing "${!prefix*}", the first character of IFS is placed between the variable names to make the output string. (Again, see below.) 
- 
-  * 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 \ 
-   <<< 'statd:x:105:65534::/var/lib/nfs:/bin/false' 
-</code> 
- 
-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 \ 
-   <<<       2  3' 
-</code> 
- 
-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 <<< 'the plain gold ring' 
-echo "=$a=" 
-=the plain gold ring= 
- 
-$ IFS=$' \t\n' read a b c <<< 'the plain gold ring' 
-$ echo "=$c=" 
-=gold ring= 
- 
-$ IFS=$' \t\n' read a b c <<< 'the    plain gold      ring' 
-$ echo "=$a= =$b= =$c=" 
-=the= =plain= =gold      ring= 
-</code> 
- 
-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 <<< '1:2:::3::4' 
-$ echo "=$a= =$b= =$c=" 
-=1= =2= =::3::4= 
-</code> 
- 
-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 
-</code> 
- 
-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. "$*" (and analogously, ${array[*]} and ${!prefix*}), IFS is used in both the quoted and unquoted forms, but it is rendered impotent in the unquoted form. Consider: 
- 
-<code bash> 
-set -- one two three 
-IFS=+ 
-echo $* 
-one two three 
-</code> 
- 
-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 "$tmp" 
-one+two+three 
-</code> 
- 
-Variable assignment skips word splitting (because there's no meaningful way to handle multiple words when there's only a single variable to put things into), so here we can see the actual value of the unquoted $*, without word splitting getting in the way. 
- 
-By definition, the delimiter we're putting between the words will be part of IFS, and therefore it will be word-split away.  There's no way to avoid that other than using a temporary variable to suppress the word-splitting, as shown above. 
- 
-This is yet another reason why you should USE MORE QUOTES!  
ubuntu/bash/the_ifs_internal_field_separator.1575675881.txt.gz · Last modified: 2020/07/15 09:30 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki