De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Julio Cezar Neves
Data de Publicação: 27 de Fevereiro de 2021
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:
$ 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"
Senhores, neste artigo pretendi mostrar duas coisas:
IFS
que, infelizmente para nós, é uma variável pouco conhecida do Shell e
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
Comentários