bash muda seu comportamento dependendo do valor da variável “IFS”

18

Quando defino a variável IFS para um espaço, bash trata vários espaços como um espaço ( myprogram é um programa que imprime os argumentos da linha de comando que recebe):

IFS=" "
x="hello   hi   world"
./myprogram $x
argv[1] = hello
argv[2] = hi
argv[3] = world

Mas quando eu defino a variável IFS para uma vírgula, bash não trata várias vírgulas como uma vírgula:

IFS=","
x="hello,,,hi,,,world"
./myprogram $x
argv[1] = hello
argv[2] = 
argv[3] = 
argv[4] = hi
argv[5] = 
argv[6] = 
argv[7] = world

Por que isso?

    
por user267935 30.12.2017 / 03:11

1 resposta

21

Isso está documentado em man bash . Uma única ocorrência de qualquer caractere no IFS que não seja espaço em branco delimita um campo.

De man bash :

The shell treats each character of IFS as a delimiter, and splits the results of the other expansions into words using these characters as field terminators. If IFS is unset, or its value is exactly <space><tab><newline>, the default, then sequences of <space>, <tab>, and <newline> at the beginning and end of the results of the previous expansions are ignored, and any sequence of IFS characters not at the beginning or end serves to delimit words. If IFS has a value other than the default, then sequences of the whitespace characters space, tab, and newline are ignored at the beginning and end of the word, as long as the whitespace character is in the value of IFS (an IFS whitespace character). Any character in IFS that is not IFS whitespace, along with any adjacent IFS whitespace characters, delimits a field. A sequence of IFS whitespace characters is also treated as a delimiter. If the value of IFS is null, no word splitting occurs. [Emphasis added.]

Exemplos: divisão de campo

Se o IFS não tiver caracteres de espaço em branco, o espaço em branco será incluído nos campos:

$ ( IFS=',' x='one , two,three'; printf "<%s>\n" $x )
<one >
< two>
<three>

Se o IFS tiver espaços em branco e uma vírgula, as seqüências de espaços em branco, seguidas por uma vírgula, seguidas por sequências de espaços em branco serão tratadas como um único delimitador:

$ ( IFS=' ,' x='one , two,three'; printf "<%s>\n" $x )
<one>
<two>
<three>

Sequências de vírgulas são interpretadas como sequências de campos vazios:

$ ( IFS=' ,' x='one,,,two,three'; printf "<%s>\n" $x )
<one>
<>
<>
<two>
<three>

Exemplos: espaço em branco inicial e final

Se o IFS não contiver espaços em branco, todos os espaços em branco à esquerda e à direita serão mantidos nos campos:

$ ( IFS=',' x='  one , two,three  ,'; printf "<%s>\n" $x )
<  one >
< two>
<three  >

Se o IFS contiver espaços em branco, todas as sequências iniciais ou finais de espaços em branco serão removidas:

$ ( IFS=' ,' x='  one , two,three  ,'; printf "<%s>\n" $x )
<one>
<two>
<three>
    
por 30.12.2017 / 03:22

Tags