Eu estava lendo este tópico: Como fazer um loop nas linhas de um arquivo?
O que é IFS? E qual é o seu uso no contexto de for-loops?
Eu estava lendo este tópico: Como fazer um loop nas linhas de um arquivo?
O que é IFS? E qual é o seu uso no contexto de for-loops?
Respostas:
IFSsignifica - é um caractere que separa os campos. No exemplo que você postou, ele está definido como novo caractere de linha ( ); então, depois que você o definir, processará o texto linha por linha. Nesse exemplo, você pode alterar o valor de (para alguma letra existente em seu arquivo de entrada) e verificar como o texto será dividido.InputInternal Field Separator\nforIFS
BTW, a partir da resposta que você postou a segunda solução é a recomendada ...
Como @jasonwryan notou, não é Inputsó Internal. O nome Inputveio do awkqual também há OFS- Output Field Separator.
Sfoi para separador na concha Bourne de onde se originou. No shell Korn e na maioria dos outros shell tipo Bourne, como agora especificado por POSIX, o Sé para Delimiter (apenas estique um pouco sua imaginação), como A::B:por exemplo, é dividido em "A", "" e "B" (sem acréscimo adicional) ""). Isso é diferente de awk's FSou a sbandeira de expansão de parâmetros de zsh.
IFSnão está diretamente relacionado ao loop, está relacionado à divisão de palavras. IFSdetermina indiretamente como a saída do comando é dividida em partes sobre as quais o loop é repetido.
Quando você tem uma substituição de variável não protegida $fooou substituição de comando $(foo), há dois casos:
"$foo"ou em uma atribuição de variável x=$foo, a sequência resultante da substituição é usada como está.$IFSé considerado um separador de palavras. Por exemplo, IFS=":"; foo="12:34::78"; echo $fooimpressões 12 34 78(com dois espaços entre 34e 78, já que há uma palavra vazia).foo="*"; echo $fooimprime a lista de arquivos no diretório atual.Para loops, como muitos outros contextos, espere uma lista de palavras. tão
for x in $(foo); do …
quebra $(foo)em palavras e trata cada palavra como um padrão glob. O valor padrão de IFSé espaço, tabulação e nova linha , portanto, se fooimprimir duas linhas hello worlde howdyo corpo do loop for executado com x=hello, então x=worlde x=howdy. Se IFSfor explicitamente alterado para conter apenas uma nova linha, o loop será executado para hello worlde howdy. Se IFSfor alterado para ser o, em seguida, o loop é executado para hell, w, rldh(onde é um caractere de nova linha) e wdy.
"IFS indirectly determines how ..."?
IFS(diretamente) determina como a saída da substituição de comando é dividida, que então (indiretamente) determina o que o loop passa.
A partir de man bash
IFS O Separador de Campo Interno usado para divisão de palavras após a expansão e para dividir linhas em palavras com o comando read builtin. O valor padrão é "<espaço> <guia> <nova linha>".
Essa é uma das variáveis internas do Bash. Ele determina como o Bash reconhece campos ou limites de palavras quando interpreta seqüências de caracteres.
Embora o padrão seja espaço em branco (espaço, tabulação e nova linha), ele pode ser alterado, por exemplo, para analisar um arquivo de dados separados por vírgula.
Além das excelentes respostas anteriores, deixe-me acrescentar que o IFS é muito útil para a análise eficiente e portátil em casos simples em combinação com o conjunto . Eficiente, porque evita o uso de subcascas e ferramentas de desova, como grep ou sed:
resolutions="640x480,320x240"
xIFS=$IFS
IFS=','
for res in $resolutions; do
xxIFS=$IFS
IFS='x'
set -- $res
width=$1
height=$2
# handle width and height
IFS=$xxIFS
done;
IFS=$xIFS
Observe que precisamos armazenar e recuperar o valor anterior do IFS para evitar quebras indesejadas em outras partes do script.