você está aqui: Home
→
Arquivo de Mensagens
Colaboração: Julio Cezar Neves
Data de Publicação: 09 de outubro de 2017
O shell tem uma variável interna chamada IFS
- Inter Field Separator
(será Tabajara? :) - cujo valor default podemos obter da seguinte forma:
$ echo "$IFS" | od -h
0000000 0920 0a0a
0000004
O programa od
com a opção -h
foi usado para gerar um dump hexadecimal
da variável. E lá podemos ver:
Valor Hexadecimal | Significado |
---|---|
09 | <TAB> |
20 | Espaço |
0a | <ENTER> |
Ou seja os separadores entre campos (tradução livre de IFS) default são o
<TAB>
, o espaço em branco e o <ENTER>
. O IFS é usado em diversas
instruções, mas seu uso é muito comum em par com o for
e/ou com o
read.
Vejamos um exemplo semelhante ao dado no Cantinho do Shell de
15/12/2006, que me inspirou
a escrever este artigo.
$ cat script1.sh
#!/bin/sh
while read linha
do
awk -F: '{print $1}' /etc/passwd > /dev/null
done < /etc/passwd
Como podemos ver este script não faz nada (sua única saída foi enviada para
/dev/null
para não deturpar os tempos de execução), mas vamos usá-lo para
avaliação dos tempos de execução.
Este script foi alterado, trocando o awk
pelo cut
, e ficando com a
seguinte cara:
$ cat script2.sh
#!/bin/sh
while read linha
do
echo $linha | cut -f1 -d: > /dev/null
done < /etc/passwd
Mais uma outra alteração, usando 99% de intrínsecos do Shell (exceto o
comando echo
) desta vez tomando partido do IFS:
$ cat script3.sh
#!/bin/sh
IFS=:
while read user lixo
do
echo $lixo > /dev/null
done < /etc/passwd
Neste último exemplo, transformamos o separador padrão em dois-pontos (:
)
e usamos sua propriedade em conjunto com o read
, isto é, o primeiro
campo veio para a variável user
e o resto para a variável lixo
.
Em seguida, fiz um script usando Shell quase puro (novamente o echo
foi o
vilão). Repare a construção ${linha%%:*}
, que é um intrínseco (built-in)
do Shell que serve para excluir da variável linha o maior casamento com
o padrão especificado (:*
- que significa "de dois-pontos em diante"),
ou seja, excluiu de linha tudo a partir do último dois-pontos, contado da
direita para a esquerda.
$ cat script4.sh
#!/bin/sh
while read linha
do
echo ${linha%%:*} > /dev/null
done < /etc/passwd
Para finalizar, adaptei o script escrito pelo incansável Rubens Queiroz que,
exceto pelo awk
, é Shell puro.
$ cat script5.sh
#!/bin/sh
for user in `awk -F: '{print $1}' /etc/passwd`
do
echo $user > /dev/null
done
Agora, o mais importante: reparem os tempos da execução de cada um deles:
$ time script1.sh real 0m0.123s user 0m0.032s sys 0m0.032s $ time script2.sh real 0m0.297s user 0m0.152s sys 0m0.084s $ time script3.sh real 0m0.012s user 0m0.004s sys 0m0.004s $ time ./script4.sh real 0m0.012s user 0m0.004s sys 0m0.008s $ time ./script5.sh real 0m0.014s user 0m0.012s sys 0m0.004s
Reparem que estas diferenças de tempo foram obtidas para um arquivo com somente 29 linhas. Veja:
$ wc -l /etc/passwd
29 /etc/passwd
Um outro uso interessante do IFS é o que vemos a seguir, primeiramente usando
o IFS default que como vimos é <TAB>
, Espaço e <ENTER>
:
$ Frutas="Pera Uva Maçã" $ set - $Frutas $ echo $1 Pera $ echo $3 Maçã
Agora, vamos alterar o IFS para fazer o mesmo com uma variável qualquer,
e para tal vamos continuar usando o famigerado /etc/passwd
:
$ Root=$(head -1 /etc/passwd) $ echo $Root root:x:0:0:root:/root:/bin/bash $ oIFS="$IFS" $ IFS=: $ set - $Root $ echo $1 root $ echo $7 /bin/bash $ IFS="$oIFS"
Senhoras e Senhores, neste artigo pretendi mostrar duas coisas:
Júlio Cézar Neves |
|
---|---|
![]() |
O 4º UNIX do mundo nasceu na Cidade Maravilhosa, mais precisamente na Cobra Computadores, onde à época trabalhava o Julio. Foi paixão à 1ª vista! Desde então, (1980) atua nessa área como especialista em Sistemas Operacionais e linguagens de programação. E foi por essa afinidade que quando surgiu o Linux foi um dos primeiros a estudá-lo com profundidade e adotá-lo como Sistema Operacional e filosofia de vida. É autor dos livros Programação Shell Linux, 11ª edição e Bombando o Shell. |