shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Acho que eh eval


From: Gustavo Chaves
Subject: Re: [shell-script] Acho que eh eval
Date: 28 Apr 2005 13:21:33 -0300
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.4

>>>>> On Thu, 28 Apr 2005 12:35:37 -0300, Julio Cezar Neves - DATAPREVRJ 
>>>>> <address@hidden> said:

  Prompt> cat Relatorio_de_nomes_incompleto.txt
  > Jurem
  > AeroS
  > Jeffe
  > Felip
  Prompt> ls -l | grep ^d
  > drwxr-xr-x    2 jneves   jneves       4096 Abr 27 14:31 AeroSmith
  > drwxr-xr-x    2 jneves   jneves       4096 Abr 27 14:31 Jefferson
  > drwxr-xr-x    2 jneves   jneves       4096 Abr 27 14:31 Jurema
  Prompt> grep -f <(cat Relatorio_de_nomes_incompleto.txt | xargs  -i echo
  > ^{}) <(ls --color=none)
  > AeroSmith
  > Jefferson
  > Jurema

Julio, eu acho que o Felipe tem razão quando fala do problema de
desempenho desta solução.  O xargs vai disparar um processo diferente
pra cara linha do arquivo Relatorio_de_nomes_incompleto.txt.  Eu usei
o strace no Linux pra capturar todas as chamadas ao execve e contei o
seguinte:

Oito processos para a sua solução:

$ grep -f <(cat Relatorio_de_nomes_incompleto.txt | xargs -i echo ^{}) <(ls 
--color=none)

  #[pid 13885] execve("/bin/grep", ["grep", "-f", "/dev/fd/63", "/dev/fd/62"], 
[/* 38 vars */]) = 0
  #[pid 13888] execve("/bin/ls", ["ls", "--color=none"], [/* 38 vars */]) = 0
  #[pid 13887] execve("/usr/bin/xargs", ["xargs", "-i", "echo", "^{}"], [/* 38 
vars */]) = 0
  #[pid 13886] execve("/bin/cat", ["cat", 
"Relatorio_de_nomes_incompleto.tx"...], [/* 38 vars */]) = 0
  #[pid 13889] execve("/bin/echo", ["echo", "^Jurem"], [/* 38 vars */]) = 0
  #[pid 13890] execve("/bin/echo", ["echo", "^AeroS"], [/* 38 vars */]) = 0
  #[pid 13891] execve("/bin/echo", ["echo", "^Jeffe"], [/* 38 vars */]) = 0
  #[pid 13892] execve("/bin/echo", ["echo", "^Felip"], [/* 38 vars */]) = 0

Note que foram quatro 'echo', um pra cada linha do arquivo.

A primeira melhoria que eu faria é trocar o <(ls --color=none) por um
mero pipe e sem a opção, já que o ls só usa código de cores se a saída
for para um terminal.  Com o pipe ele não vai fazer isso:

$ ls | grep -f <(cat Relatorio_de_nomes_incompleto.txt | xargs -i echo ^{})

  #[pid 13962] execve("/bin/ls", ["ls"], [/* 38 vars */]) = 0
  #[pid 13963] execve("/bin/grep", ["grep", "-f", "/dev/fd/63"], [/* 38 vars 
*/]) = 0
  #[pid 13966] execve("/usr/bin/xargs", ["xargs", "-i", "echo", "^{}"], [/* 38 
vars */]) = 0
  #[pid 13965] execve("/bin/cat", ["cat", 
"Relatorio_de_nomes_incompleto.tx"...], [/* 38 vars */]) = 0
  #[pid 13967] execve("/bin/echo", ["echo", "^Jurem"], [/* 38 vars */]) = 0
  #[pid 13968] execve("/bin/echo", ["echo", "^AeroS"], [/* 38 vars */]) = 0
  #[pid 13969] execve("/bin/echo", ["echo", "^Jeffe"], [/* 38 vars */]) = 0
  #[pid 13970] execve("/bin/echo", ["echo", "^Felip"], [/* 38 vars */]) = 0

A segunda melhoria seria trocar o cat por um simples redirecionamento.
(A não ser que queiramos ganhar o "Useless Use of Cat Award"
<http://laku19.adsl.netsonic.fi/era/unix/award.html> :-)

$ ls | grep -f <( <Relatorio_de_nomes_incompleto.txt xargs -i echo ^{})

  #[pid 13978] execve("/bin/ls", ["ls"], [/* 38 vars */]) = 0
  #[pid 13979] execve("/bin/grep", ["grep", "-f", "/dev/fd/63"], [/* 38 vars 
*/]) = 0
  #[pid 13981] execve("/usr/bin/xargs", ["xargs", "-i", "echo", "^{}"], [/* 38 
vars */]) = 0
  #[pid 13982] execve("/bin/echo", ["echo", "^Jurem"], [/* 38 vars */]) = 0
  #[pid 13983] execve("/bin/echo", ["echo", "^AeroS"], [/* 38 vars */]) = 0
  #[pid 13984] execve("/bin/echo", ["echo", "^Jeffe"], [/* 38 vars */]) = 0
  #[pid 13985] execve("/bin/echo", ["echo", "^Felip"], [/* 38 vars */]) = 0

Com isso já conseguimos economizar a chamada ao cat.  Mas o maior
benefício é substituir o xargs pelo sed pra evitar as múltiplas
chamadas ao echo:

$ ls | grep -f <(sed 's/^/\^/' Relatorio_de_nomes_incompleto.txt)

  #[pid 14010] execve("/bin/ls", ["ls"], [/* 38 vars */]) = 0
  #[pid 14011] execve("/bin/grep", ["grep", "-f", "/dev/fd/63"], [/* 38 vars 
*/]) = 0
  #[pid 14013] execve("/bin/sed", ["sed", "s/^/\\^/", 
"Relatorio_de_nomes_incompleto.tx"...], [/* 38 vars */]) = 0

Que tal?

Gustavo.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]