Qual é o significado exato do IFS = $ ‘\ n’?

Se o exemplo a seguir, que define a variável de ambiente IFS para um caractere de alimentação de linha …

 IFS=$'\n' 
  • O que o sinal de dólar significa exatamente ?
  • O que faz neste caso específico?
  • Onde posso ler mais sobre esse uso específico (o Google não permite caracteres especiais em pesquisas e não sei o que procurar de outra forma)?

Eu sei qual é a variável de ambiente IFS e qual é o caractere \n (alimentação de linha), mas porque não basta usar o seguinte formato: IFS="\n" (o que não funciona)?

Por exemplo, se eu quiser percorrer todas as linhas de um arquivo e quiser usar um loop for, eu poderia fazer isso:

 for line in (< /path/to/file); do echo "Line: $line" done 

No entanto, isso não funcionará corretamente, a menos que o IFS esteja definido como um caractere de feed de linha. Para fazê-lo funcionar, eu teria que fazer isso:

 OLDIFS=$IFS IFS=$'\n' for line in (< /path/to/file); do echo "Line: $line" done IFS=$OLDIFS 

Nota: Eu não preciso de outra maneira de fazer a mesma coisa, eu conheço muitos outros já … Eu só estou curioso sobre isso $'\n' e me perguntei se alguém poderia me dar uma explicação sobre isso.

Normalmente o bash não interpreta seqüências de escape em literais de string. Então, se você escrever \n ou "\n" ou '\n' , isso não é um linebreak – é a letra n (no primeiro caso) ou uma barra invertida seguida da letra n (nos outros dois casos).

$'somestring' é uma syntax para literais de string com seqüências de escape . Portanto, ao contrário de '\n' , $'\n' é na verdade um linebreak.

De http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html :

As palavras no formato “$ ‘STRING'” são tratadas de maneira especial. A palavra se expande para uma string, com caracteres de escape de barra invertida substituídos conforme especificado pelo padrão ANSI-C. Seqüências de escape de barra invertida podem ser encontradas na documentação do Bash.

Eu acho que está forçando o script a escaping do feed de linha para o padrão ANSI-C adequado.

Apenas para dar ao construtor seu nome oficial : as strings da forma $'...' são chamadas de strings ANSI C-aspas .

Ou seja, como em sequências [ANSI] C, seqüências de escape de folga são reconhecidas e expandidas para seu equivalente literal (veja abaixo a lista completa de seqüências de escape suportadas).

Após essa expansão, $'...' strings se comportam da mesma maneira que '...' – isto é, eles são tratados como literais NÃO sujeitos a qualquer [expansão] de expansões de shell .

Por exemplo, $'\n' expande para um caractere literal de nova linha – que é algo que um literal de string bash regular (se '...' ou "..." ) não pode fazer. [1]

Outra característica interessante é que strings ANSI C-cited podem escaping ' (aspas simples) como \' , o que, '...' (strings com aspas simples regulares) não pode:

 echo $'Honey, I\'m home' # OK; this cannot be done with '...' 

Lista de sequências de escape suportadas :

Sequências de escape de barra invertida, se presentes, são decodificadas da seguinte forma:

\ um alerta (sino)

\ b backspace

\ e \ E um caractere de escape (não ANSI C)

\ f feed de formulário

\ n newline

retorno de carro

guia horizontal

\ v guia vertical

\ barra invertida

\’ citação única

\” citação dupla

\ nnn o caractere de oito bits cujo valor é o valor octal nnn (um a três dígitos)

\ xHH o caractere de oito bits cujo valor é o valor hexadecimal HH (um ou dois dígitos hexadecimais)

\ uHHHH o caractere Unicode (ISO / IEC 10646) cujo valor é o valor hexadecimal HHHH (um a quatro dígitos hexadecimais)

\ UHHHHHHHH o caractere Unicode (ISO / IEC 10646) cujo valor é o valor hexadecimal HHHHHHHH (um a oito dígitos hexadecimais)

\ cx um caractere de controle-x

O resultado expandido é simples, como se o cifrão não estivesse presente.


[1] Você pode, no entanto, inserir novas linhas reais em ‘…’ e “…” strings; ou seja, você pode definir strings que abrangem várias linhas.

Recuperar o IFS padrão – este OLDIFS=$IFS não é necessário. Execute o novo IFS em subshell para evitar a substituição do IFS padrão:

 ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} ) 

Além disso, não acredito que você recupere totalmente o antigo IFS. Você deve OLDIFS="$IFS" lo para evitar quebra de linha, como OLDIFS="$IFS" .

Cadeias de caracteres com ANSI C são um ponto-chave. Graças a @ mklement0.

Você pode testar strings ANSI C-cited com o comando od.

 echo -n $'\n' | od -c echo -n '\n' | od -c echo -n $"\n" | od -c echo -n "\n" | od -c 

Saídas:

 0000000 \n 0000001 0000000 \ n 0000002 0000000 \ n 0000002 0000000 \ n 0000002 

Você pode saber o significado claramente pelas saídas.

É como recuperar o valor de uma variável:

 VAR='test' echo VAR echo $VAR 

são diferentes, então o cifrão basicamente avalia o conteúdo.