<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog do PacMan &#187; Awk</title>
	<atom:link href="http://pacman.blog.br/blog/category/awk/feed/" rel="self" type="application/rss+xml" />
	<link>http://pacman.blog.br/blog</link>
	<description>Varias Coisas, por Tiago Peczenyj</description>
	<lastBuildDate>Thu, 26 Jan 2012 13:51:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Fibonacci: alguns algoritmos efetivos em AWK</title>
		<link>http://pacman.blog.br/blog/dicas/fibonacci-alguns-algoritmos-efetivos-em-awk/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fibonacci-alguns-algoritmos-efetivos-em-awk</link>
		<comments>http://pacman.blog.br/blog/dicas/fibonacci-alguns-algoritmos-efetivos-em-awk/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 20:35:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Awk]]></category>
		<category><![CDATA[Dicas]]></category>

		<guid isPermaLink="false">http://pacman.blog.br/blog/?p=54</guid>
		<description><![CDATA[Estava apreciando hoje de manhã um post do Felipe Tonello: Analisando Número de Fibonacci e Recursividade. É um bom artigo sobre aquelas coisas que alguns podem ter visto na faculdade e são sempre uteis: matemática, analise de algoritmos e um &#8230; <a href="http://pacman.blog.br/blog/dicas/fibonacci-alguns-algoritmos-efetivos-em-awk/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Estava apreciando hoje de manhã um post do Felipe Tonello: <a href="http://felipetonello.com/blog/2009/01/30/analisando-numero-de-fibonacci-e-recursividade">Analisando Número de Fibonacci e Recursividade</a>. É um bom artigo sobre aquelas coisas que alguns podem ter visto na faculdade e são sempre uteis: matemática, analise de algoritmos e um pouco de mente aberta.</p>
<p>Imediatamente tratei de testar a velocidade dos dois algoritmos propostos usando AWK (que, por ser interpretado, pode revelar melhor as nuances entre as abordagens). Algoritmos recursivos são interessantes, principalmente quando trabalhamos com linguagens funcionais, porém algumas formas tem um custo computacional muito alto e o calculo de Fibonacci é um exemplo perfeito: para cada termo eu preciso calcular os dois termos anteriores e, então, soma-los, e isso cresce geométricamente, consumindo memória e processamento, sem falar que tenho muita repetição de código desnecessária.</p>
<p>A tecnica de programação dinâmica apresentada cria um cache de resultados, dessa forma evito boa parte do trabalho extra, veja o resultado:</p>
<pre>Fibonacci(36) pelo algoritmo recursao simples:14930352 usando 48315633 iteracoes

real    0m51.961s
user    0m23.881s
sys     0m0.012s
Fibonacci(36) pelo algoritmo programacao dinamica:14930352 usando 71 iteracoes

real    0m0.002s
user    0m0.000s
sys     0m0.000s</pre>
<p>Usando programação dinâmica eu uso muito menos de 1% do processamento necessário pela forma recursiva tradicional. Parece ótimo, não? Depende, pois eu apenas afastei o problema: ao calcular termos de alta ordem eu terei o mesmo problema, afinal o algoritmo é O[n].</p>
<p>Lembrei de um post do Ronaldo Melo Ferraz, <a href="http://logbr.reflectivesurface.com/2008/02/01/conceitos-de-programacao-tail-recursion/">Conceitos de Programação: Tail Recursion</a> enquando estava testando os algoritmos em <a href="http://www.dei.isep.ipp.pt/~paf/orgcdocs/Intro_Erlang.pdf">Erlang</a> e encontrei <a href="http://en.literateprograms.org/Fibonacci_numbers_%28Erlang%29">esta implementação</a>. A adaptação para awk é tranquila e o teste mostrou este resultado:</p>
<pre>Fibonacci(36) pelo algoritmo programacao dinamica:14930352 usando 71 iteracoes

real    0m0.002s
user    0m0.000s
sys     0m0.000s
Fibonacci(36) pelo algoritmo tail recursion:14930352 usando 38 iteracoes

real    0m0.001s
user    0m0.000s
sys     0m0.004s</pre>
<p>Um resultado ainda mais interessante, pois eu consigo obter o valor do termo com um pouco mais da metade das iterações do que usando programação dinâmica (sem onerar a memória com o cache dos resultados).</p>
<p>Esta analise é muito superficial, a ideia é apenas despertar a curiosidade sobre estes tópicos.</p>
<p>O codigo fonte utilizado nesse benchmark:<br />
<code>function Fib_normal(N) {<br />
return (N &gt; 1)? Fib_normal(N-1) + Fib_normal(N-2) : N<br />
}<br />
function Fib_dinamic(N) {<br />
if (!m[N]) m[N] = (N &gt; 1)? Fib_dinamic(N-1) + Fib_dinamic(N-2) : N<br />
return m[N]<br />
}</code></p>
<p>function Fib(N) { return Fib_tr(N,0,1); }<br />
function Fib_tr(I,R,N){<br />
return (I==0)? R : Fib_tr(I-1,N,R+N)<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://pacman.blog.br/blog/dicas/fibonacci-alguns-algoritmos-efetivos-em-awk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manipulando logs com AWK e SED</title>
		<link>http://pacman.blog.br/blog/awk/manipulando-logs-com-awk-e-sed/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=manipulando-logs-com-awk-e-sed</link>
		<comments>http://pacman.blog.br/blog/awk/manipulando-logs-com-awk-e-sed/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 17:41:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Awk]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://pacman.blog.br/blog/dicas/manipulando-logs-com-awk-e-sed/</guid>
		<description><![CDATA[Eis que a lista de shell script traz um bom desafio. Galera, tenho o seguinte log.: AAAA&#8212;&#8212;&#8212;&#8212;-campo_1&#8212;&#8212;&#8212;&#8212;-campo_2&#8212;&#8211;campo_3&#8212;-campo_4&#8212;&#8212;&#8212;- teste_1 371508787 371547453 38666 testetesteteste BBBB&#8212;&#8212;&#8212;&#8212;-campo_1&#8212;&#8212;&#8212;&#8212;-campo_2&#8212;&#8211;campo_3&#8212;-campo_4&#8212;&#8212;&#8212;- teste_2 4625081503 4651313710 26232207 testetesteteste Estou a tentar usar o awk com a seguinte função : awk &#8230; <a href="http://pacman.blog.br/blog/awk/manipulando-logs-com-awk-e-sed/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Eis que a lista de <a href="http://br.groups.yahoo.com/group/shell-script/">shell script</a> traz um bom desafio.</p>
<p><cite>Galera, tenho o seguinte log.:</p>
<p>AAAA&#8212;&#8212;&#8212;&#8212;-campo_1&#8212;&#8212;&#8212;&#8212;-campo_2&#8212;&#8211;campo_3&#8212;-campo_4&#8212;&#8212;&#8212;- <br />teste_1 371508787 371547453 38666 testetesteteste</p>
<p>BBBB&#8212;&#8212;&#8212;&#8212;-campo_1&#8212;&#8212;&#8212;&#8212;-campo_2&#8212;&#8211;campo_3&#8212;-campo_4&#8212;&#8212;&#8212;- <br />teste_2 4625081503 4651313710 26232207 testetesteteste</p>
<p>Estou a tentar usar o awk com a seguinte função : <br />awk &#8216;$1~&#8221;teste_&#8221; {print $5&#8243;;&#8221;$4}&#8217; teste > teste_.csv</p>
<p>a funcao busca realmente o que desejo:<br />$5 $4<br />testetesteteste 38666<br />testetesteteste 6232207</p>
<p>porem,, gostaria que seprasse da forma:</p>
<p>AAAA&#8212;&#8212;&#8212;&#8212;- <br />testetesteteste 38666 <br />BBBB&#8212;&#8212;&#8212;&#8212;- <br />testetesteteste 26232207 </p>
<p>Alguém tem uma dica de como fazer?</cite></p>
<p>Ah&#8230; o bom e velho <span style="font-weight:bold;">SED</span> pode resolver isso</p>
<p><code>$ sed -rn '/(^[^-]+-+).*/{s//\1/;h};<br />/^teste_/{s/.* ([^ ]+) +([^ ]+$)/\2 \1/;x;p;g;p}' arquivo.log<br />AAAA-------------<br />testetesteteste 38666<br />BBBB-------------<br />testetesteteste 26232207</code></p>
<p>Ok, ok, ta muito complicado, mas veja só:</p>
<p><code>$ sed -rn '/^[^-]+-+/h;/^teste_/{x;p;g;p}' arquivo.log <br />AAAA-------------campo_1-------------campo_2-----campo_3----campo_4----------<br />teste_1 371508787 371547453 38666 testetesteteste<br />BBBB-------------campo_1-------------campo_2-----campo_3----campo_4----------<br />teste_2 4625081503 4651313710 26232207 testetesteteste</code></p>
<p>Vamos explicar<br />1) a opção -n serve para informar ao sed &#8220;imprima apenas quando eu mandar&#8221;<br />2) a opção -p serve para utilizar expressões regulares extendidas<br />(assim não preciso escapar o quantificador + , que significa &#8220;um ou<br />mais vezes&#8221;, assim como os parentesis, para informar os grupos).</p>
<p>Eu fiz uma sacanagem. o comando h quarda o padrão num espaço chamado espaço reserva, tipo uma memória do sed, sobreescrevendo. Assim no espaço reserva eu tenho a ultima ocorrencia de uma linha do tipo,  ^[^-]+-+      ,que traduzindo significa: tudo o que começa com um ou varios caracteres diferentes de -, seguidos de um ou varios &#8211; (no caso<br />do AAAA&#8212;&#8212;&#8212;&#8212;- &#8230; ).</p>
<p>Agora, quando eu encontro uma linha que começa com teste_ eu:</p>
<p>x) troco essa linha com a linha que esta na memória (a atual<br />&#8216;teste_&#8230;&#8217; vai, outra volta).<br />p) imprimo a linha que veio (AAAA&#8212;&#8212;&#8212;- &#8230;)<br />g) pego a linha da memória (teste_&#8230;)<br />p) imprimo a linha cachorrona</p>
<p>Só que não fica como vc quer. Ai vc precisa fazer a sacanagem:</p>
<p><span style="font-style:italic;">se uma linha NÃO tem o que eu quero, então eu a manipulo habilmente<br />até que ela chegue ao que eu quero</span></p>
<p>Eu poderia ter usado varias tecnicas mas&#8230; uma vez com sed, podemos continuar nele.</p>
<p><code>$ sed -rn '/(^[^-]+-+).*/{s//\1/;h};<br />/^teste_/{s/.* ([^ ]+) +([^ ]+$)/\2 \1/;x;p;g;p}' arquivo.log</code></p>
<p>eu transformei a primera ER em  (minha_ER).* &#8212; ou seja, criei um <span style="font-style:italic;">grupo</span> para o que me interessa. basta fazer:</p>
<p><code>s/(minha_ER).*/\1/</code></p>
<p>para que toda a linha seja reduzida ao que a minha ER casa. em outras palavras, eu apaguei o resto da linha.</p>
<p>na outra eu fui mais sacana pois eu tenho 2 grupos e troco toda a linha pelos grupos, na ordem inversa. coisa de quem toma muito café e não tem escrupulos.</p>
<p>Vamos ver a versão <span style="font-weight:bold;">AWK</span>?</p>
<p><code>$ awk '/^[^-]+-+/{match($0,/^[^-]+-+/); x=substr($0,1,RLENGTH)}<br />/^teste_/{print x,"\n"$5,$4}' arquivo.log<br />AAAA-------------<br />testetesteteste 38666<br />BBBB-------------<br />testetesteteste 26232207</code></p>
<p>x, nesse caso, armazena aquele pedaço da linha anterior, que eu descobri o que é via match. match procura uma expressão regular numa string, nesse caso em $0, e seta um valor na variavel RLENGTH, que é onde a expressão acaba. basta pegar essa parte da string e guardar na variavel x, que sera lida depois.</p>
<p>Aqui fala um pouco dessas duas funções: <a href="http://people.cs.uu.nl/piet/docs/nawk/nawk_92.html">http://people.cs.uu.nl/piet/docs/nawk/nawk_92.html</a></p>
<p>Eu poderia ter resolvido dessa forma também<br /><code>$ awk '/^[^-]+-+/{sub(/-[^-]+.*$/,"-");x=$0} <br />/^teste_/{print x,"\n"$5,$4}' arquivo.log<br />AAAA-------------<br />testetesteteste 38666<br />BBBB-------------<br />testetesteteste 26232207</code></p>
<p>Entretanto aqui eu faço uma substituição grosseira do resto da linha que tem o AAAA&#8212;&#8212;&#8230; por -, abusando do .* (e o fato dele ser guloso). Parece mais simples, mas está sujeito à falhas, embora não consigo pensar em nenhuma situação que seja possivem demonstrar.</p>
<p>AWK &#038; SED são ferramentas sensacionais para esse tipo de problema <img src='http://pacman.blog.br/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://pacman.blog.br/blog/awk/manipulando-logs-com-awk-e-sed/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Um corretor ortográfico em gawk</title>
		<link>http://pacman.blog.br/blog/awk/um-corretor-ortografico-em-gawk/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=um-corretor-ortografico-em-gawk</link>
		<comments>http://pacman.blog.br/blog/awk/um-corretor-ortografico-em-gawk/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 17:39:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Awk]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://pacman.blog.br/blog/dicas/um-corretor-ortografico-em-gawk/</guid>
		<description><![CDATA[Ano passado eu publiquei uma pequena nota sobre um pequeno corretor ortográfico feito em Python. No artigo do Peter Norwig, ele explica o principio estatístico do algoritmo. No final, ele mostra varias implementações do algoritmo (em D, Java, Ruby e &#8230; <a href="http://pacman.blog.br/blog/awk/um-corretor-ortografico-em-gawk/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ano passado eu publiquei <a href="http://peczenyj.blogspot.com/2007/08/implementando-um-corretor-ortogrfico.html">uma pequena nota sobre um pequeno corretor ortográfico feito em Python</a>.</p>
<p>No <a href="http://norvig.com/spell-correct.html">artigo</a> do Peter Norwig, ele explica o principio estatístico do algoritmo. No final, ele mostra varias implementações do algoritmo (em D, Java, Ruby e até Erlang).</p>
<p>Depois de muito pesquisar, decidi fazer uma versão em gawk. A primeira tinha 30 linhas e não funcionava muito bem, arrumando e testando cheguei a esta forma final com apenas 15 linhas.</p>
<p>Eu chamo de linha um <span style="font-style:italic;">statement</span> completo do awk. Perceba que nenhuma linha dessas possui o separador de statement <span style="font-weight:bold;">;</span> (ponto-e-virgula), exceto quando estou utilizando o for no estilo C.</p>
<p><code lang="awk"><br />
# Usage: gawk -v word=something -f thisfile.awk [ big.txt [ big2.txt ... ]]<br />
# Gawk version with 15 lines -- 04/13/2008<br />
# Author: tiago (dot) peczenyj (at) gmail (dot) com<br />
# Based on : http://norvig.com/spell-correct.html<br />
function edits(w,max,candidates,list,        i,j){<br />
	for(i=0;i<  max ;++i) ++list[substr(w,0,i) substr(w,i+2)]<br />
	for(i=0;i< max-1;++i) ++list[substr(w,0,i) substr(w,i+2,1) substr(w,i+1,1) substr(w,i+3)]<br />
	for(i=0;i<  max ;++i) for(j in alpha) ++list[substr(w,0,i) alpha[j] substr(w,i+2)]<br />
	for(i=0;i<= max ;++i) for(j in alpha) ++list[substr(w,0,i) alpha[j] substr(w,i+1)]<br />
	for(i in list) if(i in NWORDS) candidates[i] = NWORDS[i] }<br />
function correct(word            ,candidates,i,list,max,temp){<br />
	edits(word,length(word),candidates,list)<br />
	if (!asort(candidates,temp)) for(i in list) edits(i,length(i),candidates)<br />
	return (max = asorti(candidates)) ? candidates[max] : word }<br />
BEGIN{ if (ARGC == 1) ARGV[ARGC++] = "big.txt" # http://norvig.com/big.txt<br />
	while(++i<=length(x="abcdefghijklmnopqrstuvwxyz")) alpha[i]=substr(x,i,1)<br />
	IGNORECASE=RS="[^"x"]+" }<br />
{      ++NWORDS[tolower($1)]   }<br />
END{   print (word in NWORDS) ? word : "correct("word")=> " correct(tolower(word)) }<br />
</code></p>
<p>Veja o script em funcionamento:
<pre>$ time gawk -v word=somethink -f spelling.awkcorrect(somethink)=> something

real    0m4.862suser    0m4.702ssys     0m0.093s</pre>
]]></content:encoded>
			<wfw:commentRss>http://pacman.blog.br/blog/awk/um-corretor-ortografico-em-gawk/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

