<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CUAGRHg7fip7ImA9WhRVGUo.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277</id><updated>2012-01-19T12:48:45.606+01:00</updated><category term="mod_proxy cors same origin policy apache" /><category term="VirtualBox clonar ubuntu linux" /><category term="cors xdm same origin policy prototype jquery" /><category term="bash variables sin definir" /><category term="rest java jersey ajax prototype jquery eclipse glassfish" /><category term="mousepad encender apagar" /><category term="gparted parted" /><category term="bash contador" /><category term="imagemagick pdf imágenes" /><category term="hg mercurial mercurial-server" /><category term="arreglos bash aleatorio" /><title>Cosas de la tecnología</title><subtitle type="html">Este blog contiene soluciones que he encontrado a problemas tecnológicos varios. Sobre todo me ha servido de referencia cuando estos se presentan de nuevo y espero -que estando disponible en la Web- pueda serle de ayuda a otros. 

Otra cosa que me he propuesto es abordar las soluciones, en la medida de lo posible, en español... Un pequeño grano de arena que pretende reducir la brecha tecnológica.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://camposer-techie.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>81</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/CosasDeLaTecnologa" /><feedburner:info uri="cosasdelatecnologa" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUAGRHgyeCp7ImA9WhRVGUo.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-3463225913062654150</id><published>2012-01-19T12:48:00.000+01:00</published><updated>2012-01-19T12:48:45.690+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-19T12:48:45.690+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="hg mercurial mercurial-server" /><title>Algunos tips para gestionar mercurial-server</title><content type="html">&lt;b&gt;Agregando usuarios&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Para agregar usuarios a una instalación de mercurial-server, basta con agregar la clave pública de la máquina -desde donde se conectará el usuario- al repo hgadmin.&lt;br /&gt;
&lt;br /&gt;
Para generar la clave pública puede ejecutar los siguientes comandos:&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ ssh-keygen -t rsa
$ cat ~/.ssh/id_rsa.pub
&lt;/pre&gt;&lt;br /&gt;
Obtenida la clave pública del usuario, deberá pegarla dentro de la carpeta keys/users/ o keys/root/ del repo hgadmin, dependiendo de si quiere que el nuevo usuario sea "ordinario" o "admin", respectivamente. Los admin pueden hacer clone del repo hgadmin (modificar usuarios).&lt;br /&gt;
&lt;br /&gt;
IMPORTANTE: Recuerde que la manera de modificar el repo hgadmin es clonarlo, modificarlo y empujar (push) los cambios al repo principal. NO MODIFIQUE DIRECTAMENTE SOBRE EL SERVIDOR!. Puede seguir los siguientes pasos:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ mkdir hgadmin-tmp &amp;&amp; cd hgadmin-tmp
$ hg clone ~hg/repos/hgadmin .
$ mkdir keys/users/newuser
$ cp ~/newuserkey keys/users/newuser
$ hg add *
$ hg ci -m "Added newuser to repo"
$ hg push
&lt;/pre&gt;&lt;br /&gt;
En el momento en que empuje los cambios al repo se agregará automáticamente la nueva clave pública al archivo ~hg/.ssh/authorized_keys, verifíquelo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creando un repositorio remoto para compartir entre diferentes usuarios&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Debe crear el proyecto en el servidor y luego clonarlo en la máquina donde desee modificar el repositorio. Para ello puede ejecutar los siguientes comandos:&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Del lado del servidor&lt;/u&gt;&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ cd ~hg/repos/
$ mkdir newrepo &amp;&amp; cd newrepo
$ hg init 
$ cd ..
$ chown -R hg.hg newrepo
&lt;/pre&gt;&lt;br /&gt;
IMPORTANTE: Dar todos los permisos al usuario dueño del proceso "mercurial-server", en este ejemplo: hg&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Del lado del cliente&lt;/u&gt;&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ mkdir newrepo &amp;&amp; cd newrepo
$ hg clone ssh://hg@hg.mydomain.com/repos/newrepo .
&lt;/pre&gt;&lt;br /&gt;
Listo, nuevo repo creado y preparado para ser utilizado!&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-3463225913062654150?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Z8JJQfNDhUFf-gY7Fp8kfwkXAI4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Z8JJQfNDhUFf-gY7Fp8kfwkXAI4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Z8JJQfNDhUFf-gY7Fp8kfwkXAI4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Z8JJQfNDhUFf-gY7Fp8kfwkXAI4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/ozHk9LeD5B0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/3463225913062654150/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2012/01/algunos-tips-para-gestionar-mercurial.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/3463225913062654150?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/3463225913062654150?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/ozHk9LeD5B0/algunos-tips-para-gestionar-mercurial.html" title="Algunos tips para gestionar mercurial-server" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2012/01/algunos-tips-para-gestionar-mercurial.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEDQHY9fCp7ImA9WhRQEUw.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-7500119031682822393</id><published>2011-12-05T21:14:00.007+01:00</published><updated>2011-12-05T21:24:31.864+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-05T21:24:31.864+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rest java jersey ajax prototype jquery eclipse glassfish" /><title>Servicios REST con Jersey y Ajax</title><content type="html">Esta semana estuve de cursos en Indra Ciudad Real, por cierto, un grupo majísimo/panísima. &lt;br /&gt;
&lt;br /&gt;
Hicimos un ejercicio de servicios &lt;a href="http://es.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; con Java, &lt;a href="http://jersey.java.net/"&gt;Jersey&lt;/a&gt;, e invocación de estos con &lt;a href="http://es.wikipedia.org/wiki/AJAX"&gt;Ajax&lt;/a&gt; (una parte &lt;a href="http://www.prototypejs.org/"&gt;Prototype&lt;/a&gt; y otra &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;) que no podía dejar pasar por alto. Utilizamos &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; como &lt;a href="http://es.wikipedia.org/wiki/Entorno_de_desarrollo_integrado"&gt;IDE&lt;/a&gt;, &lt;a href="http://db.apache.org/derby/"&gt;Derby&lt;/a&gt; como &lt;a href="http://es.wikipedia.org/wiki/Sistema_de_gesti%C3%B3n_de_bases_de_datos_relacionales"&gt;RDBMS&lt;/a&gt; y &lt;a href="http://glassfish.java.net/"&gt;Glassfish&lt;/a&gt; como &lt;a href="http://es.wikipedia.org/wiki/Servidor_de_aplicaciones#Servidores_de_aplicaci.C3.B3n_Java_EE"&gt;Servidor de Aplicaciones&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Les dejo los pasos en este artículo. El código completo lo pueden conseguir &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual.zip"&gt;aquí&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Implementamos un &lt;a href="http://es.wikipedia.org/wiki/CRUD"&gt;CRUD&lt;/a&gt; para una entidad llamada Persona. &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual/sql/persona.sql"&gt;Aquí&lt;/a&gt; les dejo la estructura de la BD.&lt;br /&gt;
&lt;br /&gt;
El código incluye tres partes y de esa forma espero abordar este artículo, a saber: &lt;a href="#dao"&gt;DAO&lt;/a&gt;, &lt;a href="#rest"&gt;Servicio REST&lt;/a&gt; e &lt;a href="#gui"&gt;Interfaz Gráfica de Usuario (GUI)&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;a name="#dao"&gt;El DAO&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Realmente aquí no hubo demasiada sofisticación, como el curso iba de Web 2.0, hicimos el menor énfasis en acceso a datos. Les dejo el pequeño &lt;a href="http://es.wikipedia.org/wiki/Data_Access_Object"&gt;DAO&lt;/a&gt; que hicimos para trabajar con la BD.&lt;br /&gt;
&lt;br /&gt;
La interfaz, pensando en el uso futuro de &lt;a href="http://es.wikipedia.org/wiki/Inversi%C3%B3n_de_control"&gt;IoC&lt;/a&gt;, la pueden conseguir &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual/src/es/indra/tiendavirtual/dao/IPersonaDAO.java"&gt;aquí&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
La clase concreta, &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual/src/es/indra/tiendavirtual/dao/PersonaDAO.java"&gt;aquí&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Si se fijan, la interfaz la implementamos siguiendo el estándar de nombrado de C# que me parece más fácil de seguir, es decir, agregamos una "I" al inicio de la interfaz. El resto es la implementación de la clase concreta. En caso de utilizar IoC, por ejemplo con &lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt;, la inicialización y destrucción de la conexión en el constructor y método finalize debería desaparecer. De hecho, como está ahora no me gusta mucho, pero lo hice de esta forma para mantener el código lo más simple posible.&lt;br /&gt;
&lt;br /&gt;
La clase Persona es simplemente un &lt;a href="http://es.wikipedia.org/wiki/Plain_Old_Java_Object"&gt;POJO&lt;/a&gt; con todos los campos de la entidad: id, nombre y apellido. El código &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual/src/es/indra/tiendavirtual/domain/Persona.java"&gt;aquí&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;a name="#rest"&gt;El Servicio REST&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
El servicio REST lo implementamos con &lt;a href="http://jersey.java.net/"&gt;Jersey&lt;/a&gt;, que facilita bastante el código.&lt;br /&gt;
&lt;br /&gt;
Para configurar Jersey se debe agregar como filtro en el Descriptor de Despliegue (web.xml), por supuesto después de haber descargado los JAR (en el proyecto dentro de WEB-INF/lib). &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual/WebContent/WEB-INF/web.xml"&gt;Clic aquí&lt;/a&gt; para ver el web.xml.&lt;br /&gt;
&lt;br /&gt;
Una vez configurado Jersey, implementamos la API, el código &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual/src/es/indra/tiendavirtual/rest/PersonaResource.java"&gt;aquí&lt;/a&gt;. Cosas importantes que destacar:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Los métodos de consulta (GET) producen JSON.&lt;/li&gt;
&lt;li&gt;Los métodos de modificación (PUT, POST y DELETE) producen HTML, success y error.&lt;/li&gt;
&lt;li&gt;El método POST está implementado para hacer POST y DELETE por restricciones impuestas por la librería Prototype (ver &lt;a href="http://www.prototypejs.org/api/ajax/options"&gt;aquí&lt;/a&gt;), para peticiones diferentes de GET y POST; ésta hace peticiones POST especificando el método en la petición a través del parámetro _method. Se puede modificar la librería para no hacer esto, pero me parece más robusto y escalable hacerlo del lado del servicio REST.&lt;/li&gt;
&lt;li&gt;Para que pudiesen "convivir" Prototype y jQuery se tuvo que activar el modo de no conflictos de jQuery, ver &lt;a href="http://docs.jquery.com/Using_jQuery_with_Other_Libraries"&gt;aquí&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
La API se puede probar utilizando &lt;a href="http://curl.haxx.se/"&gt;cURL&lt;/a&gt;. A continuación los comandos de prueba que utilizamos, que además ayudan a describir el funcionamiento de los servicios:&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ echo "GET todos"; curl -X GET -H "Content-type:text/json" -v http://localhost:8080/TiendaVirtual/rest/persona
$ echo "GET uno"; curl -X GET -H "Content-type:text/json" -v http://localhost:8080/TiendaVirtual/rest/persona/1
$ echo "PUT"; curl -X PUT -H "Content-type:application/x-www-form-urlencoded" -d "nombre=Cambiar" -d 
"apellido=Apellido" -v http://localhost:8080/TiendaVirtual/rest/persona
$ echo "POST"; curl -X POST -H "Content-type:application/x-www-form-urlencoded" -d "id=1" -d "nombre=Cambiar" -d "apellido=Apellido" -v http://localhost:8080/TiendaVirtual/rest/persona
$ echo "DELETE"; curl -X DELETE -H "Content-type:application/x-www-form-urlencoded" -d "id=1" -v http://localhost:8080/TiendaVirtual/rest/persona
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;&lt;a name="#gui"&gt;La GUI&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
La GUI la hicimos en HTML puro y utiliza una librería JS que separa las llamadas Ajax de la lógica de presentación.&lt;br /&gt;
&lt;br /&gt;
El HTML lo pueden conseguir &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual/WebContent/persona.html"&gt;aqúi&lt;/a&gt; y la librería de utilidades (donde se manejan los eventos Ajax, con Prototype y jQuery) &lt;a href="http://www.takespain.com/~camposer/REST/TiendaVirtual/WebContent/js/util.js"&gt;aquí&lt;/a&gt;. Cosas importantes que destacar:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Las llamadas de listar son síncronas, por lo que su manejo es diferente al del resto.&lt;/li&gt;
&lt;li&gt;Las llamadas de modificación (agregar, modificar, eliminar) son asíncronas y funcionan con &lt;a href="http://es.wikipedia.org/wiki/Callback_%28inform%C3%A1tica%29"&gt;callback&lt;/a&gt; sobre listar.&lt;/li&gt;
&lt;li&gt;Debido a que el código es de en un ejemplo para un curso, donde Javascript era uno de los temas, el listado se genera con DOM también (lamentablemente sólo funciona en Firefox, o al menos con &lt;a href="http://es.wikipedia.org/wiki/Gecko_%28motor_de_renderizado%29"&gt;Gecko&lt;/a&gt; como motor). Está deshabilitado por defecto, pero se puede activar con la variable TRABAJAR_DOM&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Finalmente para ejecutar: http://localhost:8080/TiendaVirtual/persona.html&lt;br /&gt;
&lt;br /&gt;
Espero este artículo sea de utilidad, sobre todo por el uso de Jersey y la invocación de la API vía Ajax. No conseguí demasiada información precisa y ejemplos que funcionaran desde el inicio. Inicialmente me apoyé bastante en el blog de Lars Vogel, &lt;a href="http://www.vogella.de/articles/REST/article.html"&gt;aquí el ejemplo&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-7500119031682822393?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yUs8sZmkSLTZyaIRfQG1kREKkEM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yUs8sZmkSLTZyaIRfQG1kREKkEM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yUs8sZmkSLTZyaIRfQG1kREKkEM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yUs8sZmkSLTZyaIRfQG1kREKkEM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/Kz_7enof458" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/7500119031682822393/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/12/servicios-rest-con-jersey-y-ajax.html#comment-form" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/7500119031682822393?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/7500119031682822393?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/Kz_7enof458/servicios-rest-con-jersey-y-ajax.html" title="Servicios REST con Jersey y Ajax" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/12/servicios-rest-con-jersey-y-ajax.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcNQ3w7fyp7ImA9WhdXEU0.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-3611276734792900204</id><published>2011-08-23T14:21:00.000+02:00</published><updated>2011-08-23T14:21:32.207+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-23T14:21:32.207+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mod_proxy cors same origin policy apache" /><title>Configurando mod_proxy para evitar CORS (por Same Origin Policy)</title><content type="html">Otra solución que conseguimos para evitar &lt;a href="http://www.w3.org/TR/cors/"&gt;CORS&lt;/a&gt; (por &lt;i&gt;&lt;a href="http://es.wikipedia.org/wiki/Pol%C3%ADtica_del_mismo_origen"&gt;Same Origin Policy&lt;/a&gt;&lt;/i&gt;) fue instalar/configurar &lt;a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html"&gt;mod_proxy&lt;/a&gt; como "proxy en reverso" en nuestro &lt;a href="http://httpd.apache.org/"&gt;Apache HTTP Server&lt;/a&gt;. Sugiero leer este artículo también: &lt;a href="http://camposer-techie.blogspot.com/2011/08/cors-xdm-same-origin-policy-prototype-y.html"&gt;CORS, XDM, Same Origin Policy, Prototype y JQuery&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Les dejo el pequeño HOWTO que hice:&lt;br /&gt;
&lt;br /&gt;
0.- Configuración del sistema&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushXml.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ cat /etc/issue
Ubuntu 10.10 \n \l

$ dpkg -l \*apache\* | grep ^i
ii  apache2-mpm-prefork                  2.2.16-1ubuntu3.1                                 Apache HTTP Server - traditional non-threaded model
ii  apache2-utils                        2.2.16-1ubuntu3.1                                 utility programs for webservers
ii  apache2.2-bin                        2.2.16-1ubuntu3.1                                 Apache HTTP Server common binary files
ii  apache2.2-common                     2.2.16-1ubuntu3.1                                 Apache HTTP Server common files
ii  libapache2-mod-php5                  5.3.3-1ubuntu9.5                                  server-side, HTML-embedded scripting language (Apache 2 module)
ii  libapache2-mod-proxy-html            3.0.1-1                                           Apache2 filter module for HTML links rewriting
&lt;/pre&gt;&lt;br /&gt;
1.- Pasos para la instalación del mod_proxy&lt;br /&gt;
&lt;br /&gt;
1.1.- Instalación de paquetes&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ sudo aptitude install libapache2-mod-proxy-html
$ sudo a2enmod proxy
$ sudo a2enmod proxy_http
&lt;/pre&gt;&lt;br /&gt;
1.2.- Configuración del VirtualHost&lt;br /&gt;
&lt;br /&gt;
Agregar al virtual host (Ej. /etc/apache2/sites-available/default) correspondiente lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;ProxyRequests Off

&lt;proxy *&gt;
Order deny,allow
Allow from all
&lt;/Proxy&gt;

ProxyPass /mio http://mio.com
ProxyPassReverse /mio http://mio.com
&lt;/pre&gt;&lt;br /&gt;
2.- Pruebas&lt;br /&gt;
&lt;br /&gt;
Simplemente bastaría con hacer una petición a: http://localhost/mio/recurso&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-3611276734792900204?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ep3kYdrd2lBMWMSkezTZ2Cg_LU0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ep3kYdrd2lBMWMSkezTZ2Cg_LU0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ep3kYdrd2lBMWMSkezTZ2Cg_LU0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ep3kYdrd2lBMWMSkezTZ2Cg_LU0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/5cGQUWK-e6s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/3611276734792900204/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/08/configurando-modproxy-para-evitar-cors.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/3611276734792900204?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/3611276734792900204?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/5cGQUWK-e6s/configurando-modproxy-para-evitar-cors.html" title="Configurando mod_proxy para evitar CORS (por Same Origin Policy)" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/08/configurando-modproxy-para-evitar-cors.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIDSXY5eSp7ImA9WhdXEU0.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-7367988807570499029</id><published>2011-08-23T13:54:00.001+02:00</published><updated>2011-08-23T13:56:18.821+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-23T13:56:18.821+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cors xdm same origin policy prototype jquery" /><title>CORS, XDM, Same Origin Policy, Prototype y JQuery</title><content type="html">Tiempo sin escribir nada por estos lados...&lt;br /&gt;
&lt;br /&gt;
Me trae de vuelta un problema que me quitó mucho tiempo y me tuvo varias horas atascado, y como este blog va de compartir problemas y soluciones en la red, pues ahí lo dejo...&lt;br /&gt;
&lt;br /&gt;
Los navegadores suelen seguir una política/restricción de seguridad conocida, llamada &lt;i&gt;&lt;a href="http://es.wikipedia.org/wiki/Pol%C3%ADtica_del_mismo_origen"&gt;Same Origin Policy&lt;/a&gt;&lt;/i&gt;, que restringe la modificación de páginas/recursos -generalmente con Javascript- con contenidos obtenidos de otro lugar diferente al "origen". Esta &lt;a href="http://en.wikipedia.org/wiki/Same_origin_policy#Origin_determination_rules"&gt;tabla&lt;/a&gt; me parece perfecta para explicar qué se considera diferente del "origen".&lt;br /&gt;
&lt;br /&gt;
Bueno, pues resulta que esta política se puede saltar valiéndose del concepto de &lt;a href="http://www.w3.org/TR/cors/"&gt;CORS&lt;/a&gt; (&lt;i&gt;Cross Origin Resource Sharing&lt;/i&gt;) o directamente utilizando una librería de XDM (&lt;i&gt;Cross Direct Messaging&lt;/i&gt;), como: &lt;a href="http://easyxdm.net/wp/"&gt;easyXDM&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Resulta que XDM nos parecía un hack y no queríamos valernos de este tipo de librerías; mucho más frecuentes en &lt;i&gt;sitemashups&lt;/i&gt;. Entonces la solución era CORS. Cumplíamos con todos los parámetros, simplemente "creíamos" enviar los parámetros básicos en nuestras peticiones HTTP, a saber: Accept, Accept-Language, Content-Language, Content-Type o Media-Type (sólo dentro del rango: application/x-www-form-urlencoded, multipart/form-data y text/plain).&lt;br /&gt;
&lt;br /&gt;
Y pasó lo que tenía que pasar, no funcionaba!! Estábamos utilizando &lt;a href="http://www.prototypejs.org/"&gt;Prototype&lt;/a&gt; porque &lt;a href="http://jquery.com/"&gt;JQuery&lt;/a&gt; no nos funcionaba en el navegador. Resulta que nuestro código si funcionaba en local, utilizando Firefox, con JQuery y seguía sin funcionar con Prototype.&lt;br /&gt;
&lt;br /&gt;
Estuve al menos 1 hora depurando/&lt;i&gt;debuggeando&lt;/i&gt; con &lt;a href="https://addons.mozilla.org/es-es/firefox/addon/firebug/"&gt;Firebug&lt;/a&gt; y la paranoia y desesperación me llevaron hasta a probar con &lt;a href="http://www.wireshark.org/"&gt;Wireshark&lt;/a&gt;. Fue cuando nos dimos cuenta de que Prototype estaba incluyendo algunos parámetros adicionales en la petición y JQuery no. &lt;br /&gt;
&lt;br /&gt;
Ya estábamos más cerca de solucionar el problema. &lt;a href="http://kourge.net/node/131"&gt;Este artículo&lt;/a&gt; abrió nuestros ojos defintivamente y agradezco de nuevo a su autor. Incluimos el código comentado allí y resolvimos el problema. Simplemente borra las cabeceras cuando detecta peticiones a recursos diferentes del origen. ¿Por qué JQuery si funcionaba? Porque cuando detecta peticiones a otro origen remueve los parámetros.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-7367988807570499029?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Eirfk5x0n-v9dECNSwA1zRPyP5s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Eirfk5x0n-v9dECNSwA1zRPyP5s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Eirfk5x0n-v9dECNSwA1zRPyP5s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Eirfk5x0n-v9dECNSwA1zRPyP5s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/6TVqH752tQs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/7367988807570499029/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/08/cors-xdm-same-origin-policy-prototype-y.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/7367988807570499029?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/7367988807570499029?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/6TVqH752tQs/cors-xdm-same-origin-policy-prototype-y.html" title="CORS, XDM, Same Origin Policy, Prototype y JQuery" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/08/cors-xdm-same-origin-policy-prototype-y.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAER3g5eSp7ImA9WhZVF0o.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-4711377033587195032</id><published>2011-05-30T17:51:00.000+02:00</published><updated>2011-05-30T17:51:46.621+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-30T17:51:46.621+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="VirtualBox clonar ubuntu linux" /><title>Clonando máquinas virtuales con VirtualBox</title><content type="html">Estuve dándome varios golpes con &lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt; para clonar una máquina virtual que había configurado con Ubuntu.&lt;br /&gt;
&lt;br /&gt;
Hasta que por fin! Lo que hice fue:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Instalar la máquina virtual fuente (vbox1). Para ello me descargué la ISO de Ubuntu Server de la Web, la configuré en el VirtualBox como CD, reinicié e instalé.&lt;/li&gt;
&lt;li&gt;Configurar la máquina virtual con dos interfaces de red. Una primera con vista "sólo anfitrión" y otra con NAT. La idea de la primera es mantener conexión con la máquina anfitrión (la no virtual) y la segunda tener acceso a Internet.&lt;/li&gt;
&lt;li&gt;Instalar todos los paquetes necesarios. En mi caso instalé: apache2, php5, php5-mysql, mysql-server y openssh-sever.&lt;/li&gt;
&lt;li&gt;Clonar la máquina. Esto me dio varios problemas de configuración de red... Al final lo que hice fue:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Seleccionar la opción de "Exportar servicio virtualizado" (CRTL+E). Para lo que generé un archivo .OVA con un nombre diferente (vbox1_1)&lt;/li&gt;
&lt;li&gt;Seleccionar la opción de "Importar servicio virtualizado" (CRTL+I). Seleccionando el archivo .OVA recientemente generado.&lt;/li&gt;
&lt;li&gt;Modificar, en opciones avanzadas, las dos direcciones MAC de las 2 interfaces de red de la nueva máquina (vbox2). Para hacer esto basta con hacer clic en el botón de refrescar. Si no se hace este paso, VirtualBox asignará las mismas direcciones de red a ambas máquinas y habrán conflictos de red.&lt;/li&gt;
&lt;li&gt;Modificar el nombre de la nueva máquina. Para esto inicié la vbox2 y cambié el nombre del host en &lt;i&gt;/etc/hosts&lt;/i&gt; y &lt;i&gt;/etc/hostname&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Borrar los parámetros heredados de direcciones MAC. Esto fue realmente problemático, como esta nueva máquina era un clon de otra, se traía las direcciones MAC de su padre y Ubuntu fallaba al reconocer las nuevas direcciones MAC. Para esto simplemente se debe eliminar el contenido del archivo: &lt;i&gt;/etc/udev/rules.d/70-persistent-net.rules&lt;/i&gt;&lt;br /&gt;
&lt;li&gt;Reiniciar. Aunque creo que bastaría con "&lt;i&gt;/etc/init.d/udev restart&lt;/i&gt;" y "&lt;i&gt;/etc/init.d/networking restart&lt;/i&gt;".&lt;/li&gt;&lt;br /&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-4711377033587195032?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rzeCqUAxQyRuZyeLrqqNpUAXmB0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rzeCqUAxQyRuZyeLrqqNpUAXmB0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rzeCqUAxQyRuZyeLrqqNpUAXmB0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rzeCqUAxQyRuZyeLrqqNpUAXmB0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/uSLFBralc0k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/4711377033587195032/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/05/clonando-maquinas-virtuales-con.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/4711377033587195032?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/4711377033587195032?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/uSLFBralc0k/clonando-maquinas-virtuales-con.html" title="Clonando máquinas virtuales con VirtualBox" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/05/clonando-maquinas-virtuales-con.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4ASHY-cCp7ImA9WhZVF0g.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-7443339312187911577</id><published>2011-05-30T12:12:00.001+02:00</published><updated>2011-05-30T12:22:29.858+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-30T12:22:29.858+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="arreglos bash aleatorio" /><title>Cogiendo N líneas aleatorías sin repetición de un archivo</title><content type="html">Se me presentó el siguiente problema: tenía un archivo con N líneas y debía tomar/coger de éste M líneas no repetidas y de forma aleatoria. Siendo M &lt; N.


Como me "da nota"/mola bash, decidí hacerlo con un script. Antes explico el algoritmo, inspirado en un método para barajar cartas:
&lt;ol&gt;&lt;br /&gt;
&lt;li&gt;Creando el mazo de cartas. Creo un arreglo con tantas posiciones como líneas tiene el archivo de entrada (el de N líneas).&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Barajando el mazo de cartas. Cojo el primer y último elemento del arreglo origen (source) y los coloco de últimos en el arreglo destino (tmp). Esto lo hago hasta vaciar el arreglo de origen y repito el procedimiento un número "aleatorio" de veces, entre 20 y 120 veces en este ejemplo. Siempre reemplazando al final de cada bucle el arreglo de origen por el temporal.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Intercambiando última y primera carta. Esto para garantizar que la primera carta no permanezca siempre igual&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Sacando M cartas del mazo. Cojo las primeras M cartas del mazo.&lt;/li&gt;&lt;br /&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash

# Variables
fileName=$1
inputLines=`wc -l $fileName | cut -d' ' -f1`
outputLines=$2 # 596 

# Filling array
for i in `seq 0 $((inputLines-1))`; do
  source[$i]=$((i+1))
done

# Shuffling array
ceil=$((RANDOM%10*10+20)) # from 20 to 120, increment 10

for rand in `seq 1 $ceil`; do

  tmpIndex=0
  for srcIndex in `seq 0 $(($inputLines/2))`; do
    let srcTopIndex=$inputLines-$srcIndex

    tmp[$tmpIndex]=${source[$srcIndex]}
    tmp[$((tmpIndex+1))]=${source[$srcTopIndex]}

    let tmpIndex+=2

  done

  # for arrays with odd length
  if [ $(($inputLines%2)) -eq 1 ]; then
    tmp[$tmpIndex]=${source[$((srcIndex+1))]}
  fi

  source=( ${tmp[@]} ) # copying tmp array
done

# Changing first element for last one
tmp=source[0]
source[0]=${source[$((inputLines-1))]}
source[$((inputLines-1))]=$tmp

# Printing random lines of input file
for i in `seq 0 $(($outputLines-1))`; do
  sed -n "${source[$i]}p" $fileName
done
&lt;/pre&gt;&lt;br /&gt;
Cosas interesantes en este ejemplo:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Manejo de arreglos: ver iteraciones, copia, extracción y asignación de valores.&lt;/li&gt;
&lt;li&gt;Extracción de una línea específica de un archivo, basado en el número de línea con sed.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-7443339312187911577?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HUrHz0qDiXb11hMdvA9-wK5Wnp0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HUrHz0qDiXb11hMdvA9-wK5Wnp0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HUrHz0qDiXb11hMdvA9-wK5Wnp0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HUrHz0qDiXb11hMdvA9-wK5Wnp0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/e4NQzcYEItc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/7443339312187911577/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/05/cogiendo-n-lineas-aleatorias-sin.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/7443339312187911577?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/7443339312187911577?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/e4NQzcYEItc/cogiendo-n-lineas-aleatorias-sin.html" title="Cogiendo N líneas aleatorías sin repetición de un archivo" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/05/cogiendo-n-lineas-aleatorias-sin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIGRHc4fyp7ImA9WhZWFEo.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-750387092397493700</id><published>2011-05-14T15:49:00.001+02:00</published><updated>2011-05-15T16:42:05.937+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-15T16:42:05.937+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mousepad encender apagar" /><title>Apagando y encendiendo el mousepad del laptop</title><content type="html">Hoy estuve peleando con mi &lt;i&gt;laptop&lt;/i&gt; tratando de encender y apagar el &lt;i&gt;mousepad&lt;/i&gt;, básicamente porque no me siento cómodo utilizándolo, para lo que conecto un &lt;i&gt;mouse&lt;/i&gt; externo, y además porque lo tropiezo al teclear, lo que se vuelve algo desesperante.&lt;br /&gt;
&lt;br /&gt;
Intenté "apagar" el &lt;i&gt;mousepad&lt;/i&gt; desde el menú de configuración del ratón, pero no conseguí ninguna opción. Entonces tuve que descubrir qué nombre tenía mi ratón, para lo que utilicé el siguiente comando:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;rodolfo@tiuna:~$ xinput list --short | grep -i 'touchpad'
⎜   ↳ SynPS/2 Synaptics TouchPad               id=12 [slave  pointer  (2)]
&lt;/pre&gt;&lt;br /&gt;
Y luego para encender y apagar el ratón fácilmente creé el siguiente &lt;i&gt;script&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;#!/bin/bash

if [ $# -gt 0 ] &amp;&amp; [ $1 == "on" ]; then
 mode=1
elif [ $# -gt 0 ] &amp;&amp; [ $1 == "off" ]; then
 mode=0
else
 echo "You must specify an option, on or off"
 echo "Usage: script.sh on"
 exit
fi

format=8

# xinput list --short | grep -i 'touchpad'
DISPLAY=:0 xinput set-int-prop 'SynPS/2 Synaptics TouchPad' 'Device Enabled' $format $mode
&lt;/pre&gt;&lt;br /&gt;
Entonces, por ejemplo para apagar el &lt;i&gt;mousepad&lt;/i&gt; bastaría con hacer:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;rodolfo@tiuna:~$ ./mousepad.sh off
&lt;/pre&gt;&lt;br /&gt;
Por cierto, tengo instalado Ubuntu 10.10, por lo que supongo que esto funcionaría como mínimo en todas las distribuciones hijas de Debian.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-750387092397493700?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QTiWkoHwyFoKus0mbW-FjAQvsYM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QTiWkoHwyFoKus0mbW-FjAQvsYM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QTiWkoHwyFoKus0mbW-FjAQvsYM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QTiWkoHwyFoKus0mbW-FjAQvsYM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/YBnk9ZuOhz4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/750387092397493700/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/05/apagando-y-encendiendo-el-mousepad-del.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/750387092397493700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/750387092397493700?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/YBnk9ZuOhz4/apagando-y-encendiendo-el-mousepad-del.html" title="Apagando y encendiendo el &lt;i&gt;mousepad&lt;/i&gt; del &lt;i&gt;laptop&lt;/i&gt;" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/05/apagando-y-encendiendo-el-mousepad-del.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4ARHY7fip7ImA9WhZXGUs.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-7020235207912596060</id><published>2011-05-09T20:49:00.000+02:00</published><updated>2011-05-09T20:49:05.806+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-09T20:49:05.806+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gparted parted" /><title>Particionando el disco de mi nueva máquina</title><content type="html">Compré una máquina este fin de semana y para instalar Linux tuve que enfrentarme al típico problema de particionamiento del disco.&lt;br /&gt;
&lt;br /&gt;
Siempre había hecho esto con Partition Magic, ahora de Symantec, pero esta vez tuvo que ser un poco diferente. &lt;br /&gt;
&lt;br /&gt;
La cuestión es que la máquina vino con Windows 7 de fábrica y quería conservarlo. La última versión pirata que conseguí del programa, siento aceptar que instalé la pirata, me estaba dando varios problemas con este Sistema Operativo.&lt;br /&gt;
&lt;br /&gt;
Pues me puse a buscar y descubrí una herramienta, seguro recontra conocida, pero totalmente desconocida por mi, &lt;a href="http://www.gnu.org/software/parted/"&gt;Parted&lt;/a&gt; y su equivalente gráfico &lt;a href="http://gparted.sourceforge.net/"&gt;Gparted&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Fue tan fácil particionar el disco que dudé hasta el final... Inicié la máquina por DVD (tengo un Ubuntu 10.10 en DVD), inicialmente ejecuté "sudo gparted", pero luego me di cuenta de que estaba en el menú de Administración.&lt;br /&gt;
&lt;br /&gt;
Borré las particiones de HP UTILS y RECOVER, para lo que previamente compré a través de la página de HP el DVD de Recovery, mero romanticismo de conservar la máquina tal cual la compré en algún futuro improbable. Y luego, instalar Ubuntu! Fáchil perolito!&lt;br /&gt;
&lt;br /&gt;
Enjoy! Recuerden, Gparted es la herramienta.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-7020235207912596060?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vYFxm7VFC8IQ2Yr00J6_MDauaYI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vYFxm7VFC8IQ2Yr00J6_MDauaYI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vYFxm7VFC8IQ2Yr00J6_MDauaYI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vYFxm7VFC8IQ2Yr00J6_MDauaYI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/C4mjknbrZNI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/7020235207912596060/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/05/particionando-el-disco-de-mi-nueva.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/7020235207912596060?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/7020235207912596060?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/C4mjknbrZNI/particionando-el-disco-de-mi-nueva.html" title="Particionando el disco de mi nueva máquina" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/05/particionando-el-disco-de-mi-nueva.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEFSHY9fCp7ImA9WhZRFkk.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-5912164453664633218</id><published>2011-04-12T23:15:00.004+02:00</published><updated>2011-04-12T23:26:59.864+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-12T23:26:59.864+02:00</app:edited><title>Ubuntu Cosillas: Xvidcap grabaciones de escritorio (una alternativa muy recomendable)</title><content type="html">Excelente!! Esto lo conseguí en el blog citado abajo, los pasos son (textual):&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Uninstall xvidcap in Synaptic&lt;/li&gt;
&lt;li&gt;Install xvidcap from http://sourceforge.net/projects/xvidcap/files/xvidcap/1.1.7/xvidcap_1.1.7jaunty_i386.deb/download&lt;/li&gt;
&lt;li&gt;Lock the installed version in Synaptic&lt;/li&gt;
&lt;li&gt;Install pavucontrol in Synaptic (Needed in Ubuntu 10.04 but not in Linux Mint 10: already present)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Open the program with padsp xvidcap&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Click on the recording button (red circle)&lt;/li&gt;
&lt;li&gt;Run pavucontrol, go to the Recording tab and there choose Monitor of Analog Stereo Internal Audio&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;a href="http://ubuntu-cosillas.blogspot.com/2010/11/xvidcap-grabaciones-de-escritorio-una.html"&gt;Ubuntu Cosillas: Xvidcap grabaciones de escritorio (una alternativa muy recomendable)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-5912164453664633218?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/B5csxWCkSUm9xMuIQzeGS3oW0Lk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/B5csxWCkSUm9xMuIQzeGS3oW0Lk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/B5csxWCkSUm9xMuIQzeGS3oW0Lk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/B5csxWCkSUm9xMuIQzeGS3oW0Lk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/9S5yqDiZWUU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/5912164453664633218/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/04/ubuntu-cosillas-xvidcap-grabaciones-de.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5912164453664633218?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5912164453664633218?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/9S5yqDiZWUU/ubuntu-cosillas-xvidcap-grabaciones-de.html" title="Ubuntu Cosillas: Xvidcap grabaciones de escritorio (una alternativa muy recomendable)" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/04/ubuntu-cosillas-xvidcap-grabaciones-de.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UFSH88eip7ImA9WhZRFEs.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-6220561956373424238</id><published>2011-04-10T22:59:00.001+02:00</published><updated>2011-04-10T23:00:19.172+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-10T23:00:19.172+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="imagemagick pdf imágenes" /><title>Barajita premiada (#24) - generando documentos PDF a partir de imágenes</title><content type="html">Por cosas de la vida necesitaba entregar un PDF con mis notas de grado escaneadas, el problema: tenía un montón de imágenes y llevarlas a un PDF con Openoffice siempre quedaba mal por inconsistencias con los márgenes. La solución:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ ls 
notas1.jpg  notas3.jpg  notas5.jpg
notas2.jpg  notas4.jpg  notas6.jpg
$ sudo aptitude install imagemagick
$ convert *.jpg notas.pdf
&lt;/pre&gt;&lt;br /&gt;
Listo! El paquete imagemagick trae el programa convert que permite manipular imágenes (formatos, tamaños, etc), éste cogió los archivos en orden (por la numeración) y generó el PDF en un pis-pas.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-6220561956373424238?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/pzynoe0jP-hut07kBW9OJ9P8bAc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pzynoe0jP-hut07kBW9OJ9P8bAc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/pzynoe0jP-hut07kBW9OJ9P8bAc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pzynoe0jP-hut07kBW9OJ9P8bAc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/fbCnK2-IfRQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/6220561956373424238/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/04/barajita-premiada-24-generando.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/6220561956373424238?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/6220561956373424238?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/fbCnK2-IfRQ/barajita-premiada-24-generando.html" title="Barajita premiada (#24) - generando documentos PDF a partir de imágenes" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/04/barajita-premiada-24-generando.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UCR346eSp7ImA9WhZREks.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-464590531057597882</id><published>2011-04-08T14:16:00.003+02:00</published><updated>2011-04-08T14:21:06.011+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-08T14:21:06.011+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bash contador" /><title>Iterando sobre un archivo con claves y consultando en BD (en bash)</title><content type="html">El problema: un archivo/fichero con columnas separadas por tuberías "|" y por cada identificador contenido en la primera columna de éste, se debía buscar en BD unos datos específicos.&lt;br /&gt;
&lt;br /&gt;
Les dejo este pequeño script que tiene algunas cosillas útiles, como la utilización de contadores en bash fácilmente (a lo C).&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash

dbuser=DB_USER
dbhost=DB_HOST
dbname=DB_NAME
ln=1 # counter
sql="SELECT ... FROM ... WHERE ... id="

cat content.csv |
while read line; do
  id=`cut -d'|' -f1 &lt;(echo $line)`

  if [ $ln -gt 1 ]; then
    mysql -u $dbuser -h $dbhost $dbname --batch --skip-column-names -e "$sql$id" | sed 's/\t/|/g'
  fi

  let ln+=1
done
&lt;/pre&gt;
Por cada línea del archivo content.csv se toma la primera columna (como id - luego de la primera línea) y luego se ejecuta una query en BD utilizando este número; el resultado es formateado con columnas separadas por tuberías. Interesante: la forma en que se incrementa el contado con "let+=1".
&lt;br/&gt;
OJO: Esto se pudo hacer con otro lenguaje de programación, ideal perl, pero como me da nota/mola bash lo hice de esta forma. Además, cabe acotar que esto es sólo algo puntual, no es una base de código que deberá mantenerse en el tiempo, de no ser así, recomendaría otra vía.

&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-464590531057597882?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5VWIZUuCWUO9OyDXKVb5igeq6-Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5VWIZUuCWUO9OyDXKVb5igeq6-Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5VWIZUuCWUO9OyDXKVb5igeq6-Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5VWIZUuCWUO9OyDXKVb5igeq6-Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/ZRDPlCHR500" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/464590531057597882/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/04/iterando-sobre-un-archivo-con-claves-y.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/464590531057597882?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/464590531057597882?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/ZRDPlCHR500/iterando-sobre-un-archivo-con-claves-y.html" title="Iterando sobre un archivo con claves y consultando en BD (en bash)" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/04/iterando-sobre-un-archivo-con-claves-y.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMCR3k9cCp7ImA9WhZSFE4.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-1094255274811649921</id><published>2011-03-29T22:56:00.003+02:00</published><updated>2011-03-29T23:01:06.768+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-29T23:01:06.768+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bash variables sin definir" /><title>Barajita premiada (#23) - variables vacías o sin definir en bash</title><content type="html">Recientemente tuve que hacer un script de bash, que entre tantas cosas, en un momento determinado debía validar y diferenciar si una variable existía o no tenía valor (era vacía).&lt;br /&gt;
&lt;br /&gt;
Para resolver el problema descubrí dos operadores que desconocía...&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash

# a equals empty string (var instance exists)
a=""
echo "${a-NO_INSTANCE}"
echo "${a:-NO_VALUE}"

# a equals full string (var instance exists)
a="hello"
echo "${a-NO_INSTANCE}"
echo "${a:-NO_VALUE}"

# b not exists as var
echo "${b-NO_INSTANCE}"
echo "${b:-NO_VALUE}"

&lt;/pre&gt;&lt;br /&gt;
Al ejecutar el script verá una salida como la siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ ./checkBashVars.sh 

NO_VALUE
hello
hello
NO_INSTANCE
NO_VALUE
&lt;/pre&gt;&lt;br /&gt;
En la salida mostrada arriba se puede ver que:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;El operador &lt;b&gt;"-"&lt;/b&gt;: devuelve el valor de la variable (VAR) si existe, no importa si es vacía. En caso de no existir, devuelve  el valor alternativo (VALOR).&lt;/li&gt;
&lt;li&gt;El operador &lt;b&gt;":-"&lt;/b&gt;: devuelve el valor de la variable (VAR) si existe y tiene valor (no es vacía). En caso de no existir, devuelve  el valor alternativo (VALOR).&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Un ejemplo para mostrar dónde se puede utilizar esto: imaginemos que tenemos un documento con identificadores, otro con registros (un CSV) donde estos identificadores están presentes y la idea es conocer cuál de los identificadores no está en el documento.&lt;br /&gt;
&lt;br /&gt;
Identificadores:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ cat ids
1
2
3
&lt;/pre&gt;&lt;br /&gt;
Fuente, CSV:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ cat source
1|nice|bad
2|welcome|bye
1|tokio|caracas
&lt;/pre&gt;&lt;br /&gt;
Script que retornará los ids que no están presentes en el documento fuente (CSV):&lt;br /&gt;
&lt;pre class="brush: bash"&gt;#!/bin/bash

cat ids |
while read id; do
        match="`grep $id'|' $source`"

        if [ "${match:-NULL}" = "NULL" ]; then
                echo $id 
        fi
done
&lt;/pre&gt;&lt;br /&gt;
La salida:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ ./script.sh 
1
&lt;/pre&gt;&lt;br /&gt;
El script mostrado arriba, busca dentro del archivo fuente (source) cada uno de los id contenidos en el archivo de ids y en el momento en que no consigue registros, porque el grep sobre el archivo retorna "NULL", imprime el id. Puede ver que el NULL es impreso utilizando el operador &lt;b&gt;:-&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-1094255274811649921?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dkeskNZi0RCinbXrrgfixr3ourA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dkeskNZi0RCinbXrrgfixr3ourA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dkeskNZi0RCinbXrrgfixr3ourA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dkeskNZi0RCinbXrrgfixr3ourA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/t02L8Z52Pjo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/1094255274811649921/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/03/barajita-premiada-23-variables-vacias-o.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/1094255274811649921?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/1094255274811649921?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/t02L8Z52Pjo/barajita-premiada-23-variables-vacias-o.html" title="Barajita premiada (#23) - variables vacías o sin definir en bash" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/03/barajita-premiada-23-variables-vacias-o.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcBRn4zeyp7ImA9WhZTEUU.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-2212992395310280873</id><published>2011-03-14T18:59:00.001+01:00</published><updated>2011-03-15T10:07:37.083+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-15T10:07:37.083+01:00</app:edited><title>Obteniendo comentarios de tablas y columnas - diccionario de datos</title><content type="html">Se presentó el típico problema de falta de documentación! Entender un sistema es complejo y paradojicamente, pareciera que cada vez más... Muchas tecnologías, muchos entornos de trabajo, muchas maneras de configurarlos, mucho... Spring, GWT, Hibernate, Symfony, CakePHP, Rails, Struts, etc, etc, etc, etc... Y etc...&lt;br /&gt;
&lt;br /&gt;
Como para rematar, más que un sistema sin documentación, una BD sin ella, es como buscar una aguja en un pajar... Como mínimo deberíamos tener un diccionario de datos y alguno de esos diagramitas (ER - Peter Chen) generados con alguna herramienta CASE.&lt;br /&gt;
&lt;br /&gt;
El problema que persigue a cualquier "UP frutado" y que además haya leído algo con aires del &lt;a href="http://agilemanifesto.org/"&gt;Manifiesto por el Desarrollo Ágil de Software&lt;/a&gt; es: si debe generar ese diccionario en un documento que seguramente no será actualizado más nunca en la vida y del que no podrá generarse un artefacto de software.&lt;br /&gt;
&lt;br /&gt;
Idealmente, en un modelo bottom-up, podemos comenzar con un CASE e ir incluyendo los comentarios según realizamos el modelo y al generar nuestro script SQL, pum! Ya tenemos comentarios en BD.&lt;br /&gt;
&lt;br /&gt;
Ahora, todo esto es bello como la pradera, pero mentira como el comercial de Coca-Cola (el de la canción de Oasis, Whatever). Esto seguramente no se actualizará más nunca en la vida.&lt;br /&gt;
&lt;br /&gt;
Con base en todo lo que he mencionado, decidí incluir los comentarios en BD directamente. Y cuando deseo leerlos, pues lo hago con el MySQL Admin.&lt;br /&gt;
&lt;br /&gt;
Ahora, qué pasa si el jefe o alguien no técnico quiere esa info... O simplemente quieres tenerla en otro formato... Precisamente ese fue uno de los problemas con los que me conseguí y realmente MySQL no me daba una herramienta que se adaptara a lo que necesitaba... Les dejo este sencillo script que pretende facilitarles la vida... Por supuesto, se pueden incluir muchas más cosas en la salida:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash

if [ $# -lt 3 ]; then
        echo "You must specify table, schema and host"
        echo "Eg. script.sh TABLE SCHEMA 192.168.10.1"
        exit
fi

table="$1"
schema="$2"
host="$3"
user="root"

stty -echo
read -p "Enter MySQL's Admin password: " password
stty echo
echo

mysql -u $user --password=$password -h $host --batch information_schema --skip-column-names -e "SELECT table_name, table_comment FROM tables WHERE table_name='$table' AND table_schema='$schema'" | sed 's/\t/|/g'

mysql -u $user --password=$password -h $host --batch information_schema --skip-column-names -e "SELECT column_name, column_type, column_comment FROM columns WHERE table_name='$table' AND table_schema='$schema'" | sed 's/\t/|/g'
&lt;/pre&gt;&lt;br /&gt;
El script de arriba imprime campos separados por tuberías "|". Específicamente, nombre de tabla, nombre de columnas, tipos y comentarios. Un ejemplo de salida:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ ./extractComments.sh mia test localhost 
Enter MySQL's Admin password: 
mia|Descripcion de la tabla
id|int(11)|Descripcion del campo id
name|varchar(50)|
&lt;/pre&gt;&lt;br /&gt;
Y puede utilizar esta variante para extraer el "Diccionario de Datos" de toda la BD:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;#!/bin/bash

if [ $# -lt 2 ]; then
        echo "You must specify table, schema and host"
        echo "Eg. script.sh SCHEMA 192.168.10.1"
        exit
fi

schema="$1"
host="$2"
user="Admin"

stty -echo
read -p "Enter MySQL's Admin password: " password
stty echo
echo

mysql -u $user --password=$password -h $host --batch $schema --skip-column-names -e "SHOW TABLES" |
while read table; do

  mysql -u $user --password=$password -h $host --batch information_schema --skip-column-names -e "SELECT table_name, table_comment FROM tables WHERE table_name='$table' AND table_schema='$schema'" | sed 's/\t/|/g'

  mysql -u $user --password=$password -h $host --batch information_schema --skip-column-names -e "SELECT column_name, column_type, column_comment FROM columns WHERE table_name='$table' AND table_schema='$schema'" | sed 's/\t/|/g'

  echo; echo
done;
&lt;/pre&gt;&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-2212992395310280873?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/P90pZ3cVlYjEUzaCz_qz-aEGkuM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/P90pZ3cVlYjEUzaCz_qz-aEGkuM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/P90pZ3cVlYjEUzaCz_qz-aEGkuM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/P90pZ3cVlYjEUzaCz_qz-aEGkuM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/qACABao1fac" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/2212992395310280873/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/03/obteniendo-comentarios-de-tablas-y.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/2212992395310280873?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/2212992395310280873?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/qACABao1fac/obteniendo-comentarios-de-tablas-y.html" title="Obteniendo comentarios de tablas y columnas - diccionario de datos" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/03/obteniendo-comentarios-de-tablas-y.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4GSXc9fSp7ImA9Wx9aGEU.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-8706925760371072814</id><published>2011-03-11T23:14:00.002+01:00</published><updated>2011-03-12T01:15:28.965+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-12T01:15:28.965+01:00</app:edited><title>Barajita premiada (#22) - copiando en consola con barra de progreso</title><content type="html">Copiar ficheros de un lado a otro por consola resulta trivial, esto se puede hacer utilizando el comando cp. Luego, hay momentos en los que se debe copiar mucha información... Por ejemplo, yo hago respaldos de mi info en un disco externo cada cierto tiempo y son varios gigas, entonces al hacer una copia no conocía nada del estatus de la copia, sólo me quedaba la persignación... XD&lt;br /&gt;
&lt;br /&gt;
Podría pensar que soy un freak por hacer copias por consola, la cuestión es que es mucho más útil porque puedo manipular la salida de error estándar y no dejo colgada la interfaz gráfica!&lt;br /&gt;
&lt;br /&gt;
Generalmente hacía algo como:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;# cp -r /etc/ /home/ /opt/ /root/ /var/ 201111_respaldo_linux 2&gt;201111_respaldo_linux/errores
&lt;/pre&gt;&lt;br /&gt;
Ahora, sólo sabía como iba esto cuando terminaba... Como máximo podía ir viendo errores con un "tail -f" sobre el fichero de errores, algo así:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;# cp -r /etc/ /home/ /opt/ /root/ /var/ 201111_respaldo_linux 2&gt;201111_respaldo_linux/errores &amp; tail -f 201111_respaldo_linux/errores
&lt;/pre&gt;&lt;br /&gt;
Pero ya no sufro más!!! Encontré una mejor manera de hacer esto, utilizando rsync que me da detalle del progreso de la operación...&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;# rsync -aRv --progress --delete /etc/ /home/ /opt/ /root/ /var/ 201111_respaldo_linux 2&gt;201111_respaldo_linux/errores
&lt;/pre&gt;&lt;br /&gt;
Esto mostrará el estatus de la copia (al más puro estilo scp), las opciones: -a, -R, -v, --progress y --delete, las utilizo -respectivamente- para: copiar ficheros, utilizar nombres relativos, activar modo verboso, mostrar progreso y eliminar contenidos diferentes de la fuente en el destino.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-8706925760371072814?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CEBt1GwOwFUROpgwBSmaROikpug/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CEBt1GwOwFUROpgwBSmaROikpug/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CEBt1GwOwFUROpgwBSmaROikpug/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CEBt1GwOwFUROpgwBSmaROikpug/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/ImvKinvBfkU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/8706925760371072814/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/03/barajita-premiada-22-copiando-en.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/8706925760371072814?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/8706925760371072814?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/ImvKinvBfkU/barajita-premiada-22-copiando-en.html" title="Barajita premiada (#22) - copiando en consola con barra de progreso" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/03/barajita-premiada-22-copiando-en.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYNQHo8eyp7ImA9Wx9aGEU.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-315042034824532096</id><published>2011-02-28T00:09:00.003+01:00</published><updated>2011-03-11T23:39:51.473+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-11T23:39:51.473+01:00</app:edited><title>Optimizando tablas InnoDB en MySQL</title><content type="html">Cuando utilizamos MySQL es común optimizar tablas con muchos registros con cierta periodicidad, esto para solventar problemas de fragmentación, entre otros. La verdad esta es una de las cosas del modelo de PostgreSQL que echo en falta, quizás no es tan "amigable" pero todo queda claro desde el inicio.&lt;br /&gt;
&lt;br /&gt;
En PostgreSQL hay un proceso de aspiradora (vacuum) que va eliminando periódicamente registros inutilizados en tablas, su configuración, pan nuestro de cada día para un admin de BBDD que debe ajustarlo con frecuencia.&lt;br /&gt;
&lt;br /&gt;
Bueno.... Volviendo a MySQL, si necesita optimizar tablas InnoDB, lo mejor que puede utilizar son ALTER nulos, estas son instrucciones DDL de tipo ALTER sin parámetros que permiten seguir trabajando con las BBDD, porque realiza copias temporales en disco. La cuestión es que esta herramienta "reconstruye" la tabla y elimina, entre otros, los problemas de fragmentación.&lt;br /&gt;
&lt;br /&gt;
Aquí les dejo un script para optimizar de "un sólo golpe" varias tablas InnoDB:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash

if [ $# -lt 2 ]; then
        echo "You must specify database host"
        echo "Eg. script.sh MY_DATABSE 192.168.10.1"
        exit
fi

db="$1"
host="$2"
user="root"
declare -a tables=(Table1 Table2 Table3)

stty -echo
read -p "Enter MySQL's Admin password: " password
stty echo

for table in ${tables[@]}; do
        echo $table &amp;&amp;
        time mysql -u $user --password=$password -h $host $db -e "ALTER TABLE $table ENGINE=INNODB"
done
&lt;/pre&gt;&lt;br /&gt;
Básicamente optimizamos las tablas especificadas (en un arreglo) e imprimimos el tiempo que toma cada instrucción (time).&lt;br /&gt;
&lt;br /&gt;
Si tiene la certeza de que todas las tablas de una BD son InnoDB y quiere optimizarlas todas aún más rápido, puede hacerlo valiéndose del comando "show tables"...&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;#!/bin/bash

if [ $# -lt 2 ]; then
        echo "You must specify database host"
        echo "Eg. script.sh MY_DATABSE 192.168.10.1"
        exit
fi

db="$1"
host="$2"
user="root"

stty -echo
read -p "Enter MySQL's Admin password: " password
stty echo

mysql -u $user --password=$password -h $host --batch --skip-column-names $db -e "SHOW TABLES" |
while read table; do
        echo $table &amp;&amp;
        time mysql -u $user --password=$password -h $host $db -e "ALTER TABLE $table ENGINE=INNODB"
done
&lt;/pre&gt;&lt;br /&gt;
La única diferencia es que las tablas ya no son especificadas a través de un arreglo (que recomiendo para BBDD grandes, donde optimizar todas las tablas podría demorar toda la vida), sino que se toman directamente del comando "SHOW TABLES" para una BD especificada.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-315042034824532096?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/azOxeDsFBh5WJ6H8Ovqoe3Y9AnA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/azOxeDsFBh5WJ6H8Ovqoe3Y9AnA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/azOxeDsFBh5WJ6H8Ovqoe3Y9AnA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/azOxeDsFBh5WJ6H8Ovqoe3Y9AnA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/uhjqGuU5a58" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/315042034824532096/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/02/optimizando-tablas-innodb-en-mysql.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/315042034824532096?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/315042034824532096?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/uhjqGuU5a58/optimizando-tablas-innodb-en-mysql.html" title="Optimizando tablas InnoDB en MySQL" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/02/optimizando-tablas-innodb-en-mysql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4MQns8fip7ImA9Wx9bF08.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-2064163514806014794</id><published>2011-02-26T14:42:00.002+01:00</published><updated>2011-02-26T14:46:23.576+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-26T14:46:23.576+01:00</app:edited><title>Ejecutando lotes de modificaciones (INSERT, UPDATE, DELETE) en BBDD</title><content type="html">Esta me salvó hace poco de un proceso de modificaciones (INSERT, UPDATE y DELETE) eterno!&lt;br /&gt;
&lt;br /&gt;
Si necesita realizar muchas operaciones de las comentadas, por ejemplo un par de millones, resulta bastante útil y reduce considerablemente el tiempo de respuesta, incluir BEGIN y COMMIT al comienzo y final del lote. &lt;br /&gt;
&lt;br /&gt;
Con esto eliminamos sobrecarga realizando una sola transacción y no una por instrucción. Espero sea de utilidad... Recuerde: BEGIN; INSERT...; COMMIT;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-2064163514806014794?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DTgu7SuPYBzIbkC0EerQsYBxTd4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DTgu7SuPYBzIbkC0EerQsYBxTd4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DTgu7SuPYBzIbkC0EerQsYBxTd4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DTgu7SuPYBzIbkC0EerQsYBxTd4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/sCQwu0R7a_s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/2064163514806014794/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/02/ejecutando-lotes-de-modificaciones.html#comment-form" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/2064163514806014794?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/2064163514806014794?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/sCQwu0R7a_s/ejecutando-lotes-de-modificaciones.html" title="Ejecutando lotes de modificaciones (INSERT, UPDATE, DELETE) en BBDD" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/02/ejecutando-lotes-de-modificaciones.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMERn45fip7ImA9Wx9bF08.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-8785984064697569848</id><published>2011-02-26T14:36:00.000+01:00</published><updated>2011-02-26T14:36:47.026+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-26T14:36:47.026+01:00</app:edited><title>Barajita premiada (#21) - número de días en un mes</title><content type="html">Esta es una barajita breve, pero no por ello menos útil. Se trata de un método sencillo en *nix de obtener el número de días que tiene un mes:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ month=02; year=2011
$ cal $month $year | xargs | awk '{print $NF}'
28
&lt;/pre&gt;&lt;br /&gt;
Obtengo los días en formato calendario, los paso por xargs para quitar retornos de carro/tabulaciones y luego pido el último elemento con AWK.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-8785984064697569848?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/stZNY3KNcXprK8TRIqT1crukVLQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/stZNY3KNcXprK8TRIqT1crukVLQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/stZNY3KNcXprK8TRIqT1crukVLQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/stZNY3KNcXprK8TRIqT1crukVLQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/P6TNQUU-uVw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/8785984064697569848/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/02/barajita-premiada-21-numero-de-dias-en.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/8785984064697569848?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/8785984064697569848?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/P6TNQUU-uVw/barajita-premiada-21-numero-de-dias-en.html" title="Barajita premiada (#21) - número de días en un mes" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/02/barajita-premiada-21-numero-de-dias-en.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIHQH0-cSp7ImA9Wx9WFEg.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-5377863059521868144</id><published>2011-01-19T18:18:00.000+01:00</published><updated>2011-01-19T18:18:51.359+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-19T18:18:51.359+01:00</app:edited><title>Instalando dos versiones de PHP-CLI en una misma máquina</title><content type="html">El otro día tuvimos problemas instalando dos versiones del interprete de línea de comandos de  PHP (PHP-CLI) en una misma máquina, específicamente, queríamos instalar en una máquina con Ubuntu 10.04 que ya tenía PHP5.2, PHP5.3.&lt;br /&gt;
&lt;br /&gt;
Mi primo Daniel (http://dcestari.posterous.com/), quien es un crack como dicen por estos lares (en Venezuela diríamos un duro), dió con la solución...&lt;br /&gt;
&lt;br /&gt;
Descargó el fichero con los fuentes de php.net y configuró utilizando las opciones que trae el &lt;i&gt;.deb&lt;/i&gt; que descargas desde los repos. A continuación las opciones:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;# ./configure --prefix=/usr/local/ --disable-cgi \
--program-suffix=5.3 \
--with-config-file-path=/etc/php5.3/cli \
--with-config-file-scan-dir=/etc/php5.3/cli/conf.d \
--build=$(dpkg-architecture -qDEB_HOST_GNU_TYPE) \
--host=$(dpkg-architecture -qDEB_HOST_GNU_TYPE) \
--sysconfdir=/etc \
--localstatedir=/var \
--disable-debug \
--with-regex=php \
--disable-rpath \
--disable-static \
--with-pic \
--with-layout=GNU \
--enable-calendar \
--enable-sysvsem \
--enable-sysvshm \
--enable-sysvmsg \
--enable-bcmath \
--with-bz2 \
--enable-ctype \
--with-db4 \
--without-gdbm \
--with-iconv \
--enable-exif \
--enable-ftp \
--with-gettext \
--enable-mbstring \
--with-pcre-regex=/usr \
--enable-shmop \
--enable-sockets \
--enable-wddx \
--with-libxml-dir=/usr \
--with-zlib \
--with-kerberos=/usr \
--with-openssl=/usr \
--enable-soap \
--enable-zip \
--with-mhash=yes \
--with-libedit \
--without-mm \
--enable-pdo \
--with-pdo-mysql \
--with-mysql --without-sybase-ct --with-sqlite \
--without-mssql --with-sqlite3 --enable-pcntl \
--without-pear
&lt;/pre&gt;&lt;br /&gt;
Luego, compilamos con &lt;i&gt;make&lt;/i&gt; y lo novedoso.... en lugar de instalar el compilado con el típico &lt;i&gt;make install&lt;/i&gt;, el descubrimiento del año (al menos para mi), utilizamos &lt;i&gt;checkinstall&lt;/i&gt; lo que genera un &lt;i&gt;.deb&lt;/i&gt; -con el nombre especificado- que después se puede instalar y desinstalar fácilmente con &lt;i&gt;dpkg&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-5377863059521868144?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wyhtdePcA8Zyrc3yLSDeZbBuvaA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wyhtdePcA8Zyrc3yLSDeZbBuvaA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wyhtdePcA8Zyrc3yLSDeZbBuvaA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wyhtdePcA8Zyrc3yLSDeZbBuvaA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/DUNs8v2Io6g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/5377863059521868144/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/01/instalando-dos-versiones-de-php-cli-en.html#comment-form" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5377863059521868144?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5377863059521868144?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/DUNs8v2Io6g/instalando-dos-versiones-de-php-cli-en.html" title="Instalando dos versiones de PHP-CLI en una misma máquina" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/01/instalando-dos-versiones-de-php-cli-en.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUBRXc8fyp7ImA9Wx9XFko.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-5645025874937182634</id><published>2011-01-10T16:44:00.000+01:00</published><updated>2011-01-10T16:44:14.977+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-10T16:44:14.977+01:00</app:edited><title>Copiando permisos de una BD MySQL a otra</title><content type="html">Este script lo encontré en la red y me pareció que debía publicarlo aquí por su gran utilidad:&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash
# adapted from (http://www.pyrosoft.co.uk/blog/2006/10/18/show-grants-for-all-users-on-mysql/)
mysql --batch --skip-column-names -e "SELECT user, host FROM user" mysql |
while read user host; do
  echo "# $user @ $host"
  mysql --batch --skip-column-names -e"SHOW GRANTS FOR '$user'@'$host'"
done
&lt;/pre&gt;&lt;br /&gt;
El script mostrado arriba saca todos los usuarios de la BD y luego retorna un script con los privilegios para cada uno de estos, lo que permitiría migrar privilegios y usuarios de una BD MySQL a otra.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-5645025874937182634?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/oMtAmqQ-EDqOvvQcSwTVH2GyPO4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oMtAmqQ-EDqOvvQcSwTVH2GyPO4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/oMtAmqQ-EDqOvvQcSwTVH2GyPO4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oMtAmqQ-EDqOvvQcSwTVH2GyPO4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/sTyemSwH8ro" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/5645025874937182634/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2011/01/copiando-permisos-de-una-bd-mysql-otra.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5645025874937182634?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5645025874937182634?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/sTyemSwH8ro/copiando-permisos-de-una-bd-mysql-otra.html" title="Copiando permisos de una BD MySQL a otra" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2011/01/copiando-permisos-de-una-bd-mysql-otra.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUFRHo6eyp7ImA9Wx9RE04.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-3241514455029529339</id><published>2010-12-14T15:33:00.000+01:00</published><updated>2010-12-14T15:33:35.413+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-14T15:33:35.413+01:00</app:edited><title>Barajita premiada (#20) - seq con formato</title><content type="html">Típico que necesita sacar por consola una secuencia de números, entonces utiliza el comando seq, por ejemplo:&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ seq 1 5 
1
2
3
4
5
&lt;/pre&gt;&lt;br /&gt;
O necesita esos números de dos en dos:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ seq 1 2 5
1
3
5
&lt;/pre&gt;&lt;br /&gt;
La cosa se pone interesante cuando requiere formatos, por ejemplo obtener siempre números de dos cifras, entonces puede utilizar:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;$ seq -f "%02g" 1 5
01
02
03
04
05
&lt;/pre&gt;&lt;br /&gt;
A este punto usted se preguntará, ¿y para qué puede serme útil esto? Pues yo no lo sé, no mentira, esto podría resultar útil para -por ejemplo- filtrar entradas de un log de apache donde cada línea lleva algo como:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;192.168.0.1 - - [01/Nov/2010:00:00:33 +0100] "GET ..." 
&lt;/pre&gt;&lt;br /&gt;
Si quisiera extraer cada entrada para un día específico podría utilizar un script del tipo:&lt;br /&gt;
&lt;pre class="brush: bash"&gt;#!/bin/bash

for day in `seq -f "%02g" 1 31`; do
  count=`egrep -i "\[$day/Nov/[0-9:+ ]+\] \"GET $line" logs/*access.$month.log | grep " 200 " | wc -l`
  echo "$day,$line: $count"
done
&lt;/pre&gt;&lt;br /&gt;
¿Y para qué sirvió el seq? para hacer un "for" con valores de dos dígitos y que así tuviera sentido el grep que hacemos dentro del búcle (ver: $day). &lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-3241514455029529339?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/T_H8IRXPgPQlNNPEHN1cgfQfTeg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T_H8IRXPgPQlNNPEHN1cgfQfTeg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/T_H8IRXPgPQlNNPEHN1cgfQfTeg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T_H8IRXPgPQlNNPEHN1cgfQfTeg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/py7ME93Zqfc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/3241514455029529339/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2010/12/barajita-premiada-20-seq-con-formato.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/3241514455029529339?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/3241514455029529339?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/py7ME93Zqfc/barajita-premiada-20-seq-con-formato.html" title="Barajita premiada (#20) - seq con formato" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2010/12/barajita-premiada-20-seq-con-formato.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIERXw6cSp7ImA9Wx9TFU8.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-8566538493370257528</id><published>2010-11-23T15:45:00.000+01:00</published><updated>2010-11-23T15:45:04.219+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-23T15:45:04.219+01:00</app:edited><title>Buscando campos únicos en archivos separados por caracteres (Ej. CSV)</title><content type="html">El comando uniq me devuelve, para un conjunto generalmente ordenado previamente (ver: sort), un listado de líneas únicas. Inclusive me puede ayudar a contar el número de coincidencias.&lt;br /&gt;
&lt;br /&gt;
¿El problema? Cuando tengo un archivo con campos separados por caracteres, como un CSV, ¿cómo hago para pedirle sólo únicos para determinados campos del archivo? Pues como Master Card, para todo lo demás AWK ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ cat a
1|1|2
1|2|3
1|1|5
2|6|7
$ awk -F '|' '!x[$1]++' a
1|1|2
2|6|7
$ awk -F '|' '!x[$1,$2]++' a
1|1|2
1|2|3
2|6|7
&lt;/pre&gt;&lt;br /&gt;
Fíjese que para el archivo "a" con campos separados por tuberías "|" extraigo los caracteres únicos, primero considerando el primer campo y luego considerando los primeros dos, Esto no podría hacerse fácilmente con uniq porque tendría que utilizar la vaga y precaria función -skip-chars.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-8566538493370257528?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/91YGUTSkR6HpyqoXguVkFK5KY8U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/91YGUTSkR6HpyqoXguVkFK5KY8U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/91YGUTSkR6HpyqoXguVkFK5KY8U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/91YGUTSkR6HpyqoXguVkFK5KY8U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/T5WywwzUAXU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/8566538493370257528/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2010/11/buscando-campos-unicos-en-archivos.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/8566538493370257528?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/8566538493370257528?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/T5WywwzUAXU/buscando-campos-unicos-en-archivos.html" title="Buscando campos únicos en archivos separados por caracteres (Ej. CSV)" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2010/11/buscando-campos-unicos-en-archivos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkAHSXY-fSp7ImA9Wx5bEE4.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-6617788705326373813</id><published>2010-10-25T21:25:00.000+02:00</published><updated>2010-10-25T21:25:38.855+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-25T21:25:38.855+02:00</app:edited><title>Transformando un archivo de ids en X para reemplazar en queries del tipo SELECT ... WHERE id IN (X)</title><content type="html">Otra útil... típico que tenemos un archivo con un montón de ids y queremos meterlos dentro de alguna query del tipo "WHERE field IN (X)", donde X está formado por todos los ids. Este comando retorna X.&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ awk -v _SQ="'" 'NR&gt;1 { retorno = retorno ", " _SQ $0 _SQ } END { print retorno }' ids 
&lt;/pre&gt;&lt;br /&gt;
El archivo ids contiene un id por línea. &lt;br /&gt;
&lt;br /&gt;
* Este ejemplo siempre agrega un id vacio ('') al comienzo, para quitarlo basta agregar un IF. Yo lo he dejado porque me conviene en la mayoría de casos.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-6617788705326373813?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/x1tU2vw9o8GT12rvH2IXJsW_TOA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x1tU2vw9o8GT12rvH2IXJsW_TOA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/x1tU2vw9o8GT12rvH2IXJsW_TOA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x1tU2vw9o8GT12rvH2IXJsW_TOA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/csQa7KFZ2c0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/6617788705326373813/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2010/10/transformando-un-archivo-de-ids-en-x.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/6617788705326373813?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/6617788705326373813?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/csQa7KFZ2c0/transformando-un-archivo-de-ids-en-x.html" title="Transformando un archivo de ids en X para reemplazar en queries del tipo SELECT ... WHERE id IN (X)" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2010/10/transformando-un-archivo-de-ids-en-x.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEBSXw8fCp7ImA9Wx5bEE4.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-5659537300146986518</id><published>2010-10-25T21:07:00.000+02:00</published><updated>2010-10-25T21:07:38.274+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-25T21:07:38.274+02:00</app:edited><title>Cómo enviar la salida de una query a un archivo separado por "comas" (mysql)</title><content type="html">Esta es sencilla pero útil, cómo ejecutar una query y enviar su salida a un archivo separado por comas (o cualquier otro caracter). En PostgreSQL es trivial, pero en MySQL no existe (o al menos no lo he conseguido) un parámetro que defina un FS (field separator).&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;$ mysql -u root db_name &lt; query | sed 's/\t/|/g' | tee output.csv
&lt;/pre&gt;

Dentro del archivo query está la QUERY. La salida, producto de ejecutar la query, la procesamos con sed reemplazando TABS (\t) por PIPES* (|). 
&lt;br/&gt;&lt;br/&gt;
* En lugar de PIPES podrían ser comas, pero no recomiendo ese caracter porque es muy común.

&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-5659537300146986518?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Rb0u25iLAABdGUaJlfXvodDftIg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rb0u25iLAABdGUaJlfXvodDftIg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Rb0u25iLAABdGUaJlfXvodDftIg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rb0u25iLAABdGUaJlfXvodDftIg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/fH86EZ8yRPo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/5659537300146986518/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2010/10/como-enviar-la-salida-de-una-query-un.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5659537300146986518?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5659537300146986518?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/fH86EZ8yRPo/como-enviar-la-salida-de-una-query-un.html" title="Cómo enviar la salida de una query a un archivo separado por &quot;comas&quot; (mysql)" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2010/10/como-enviar-la-salida-de-una-query-un.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUFRHc8eSp7ImA9Wx5VGEQ.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-2905871213600258623</id><published>2010-10-12T17:43:00.000+02:00</published><updated>2010-10-12T17:43:35.971+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-12T17:43:35.971+02:00</app:edited><title>Barajita premiada (#19) - cut &amp; paste</title><content type="html">Estos dos comandos son súper útiles cuando deseamos generar archivos &lt;a href="http://es.wikipedia.org/wiki/CSV"&gt;CSV&lt;/a&gt; a partir de otros CSV. Sobre todo cuando necesitamos pegar columnas con otras (verticalmente). Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;rodolfo@rcampos-laptop:~/cutAndPaste$ cat a 
id|nombre|apellido|nombreCompleto
1|Rodolfo|Campos|Rodolfo Campos
2|Juan|Pérez|Juan Pérez
rodolfo@rcampos-laptop:~/cutAndPaste$ cat b
id|cédula
1|12345678
2|87654321
rodolfo@rcampos-laptop:~/cutAndPaste$ cut -d'|' -f2 b | paste -d '|' a -
id|nombre|apellido|nombreCompleto|cédula
1|Rodolfo|Campos|Rodolfo Campos|12345678
2|Juan|Pérez|Juan Pérez|87654321
&lt;/pre&gt;&lt;br /&gt;
En el ejemplo mostrado arriba hacemos lo siguiente:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Cortamos la segunda columna del archivo "b" (opción -f), especificando el delimitador (-d).&lt;/li&gt;
&lt;li&gt;Pegamos la salida después del contenido de "a" y la separación de ambos archivos es marcada con un "|" (opción -d). Note que la salida que viene de la tubería (del comando anterior) se especifica como entrada del comando paste utilizando un guión.&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-2905871213600258623?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zjulxQdHY2875eOJ5feS4FC9LV8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zjulxQdHY2875eOJ5feS4FC9LV8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zjulxQdHY2875eOJ5feS4FC9LV8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zjulxQdHY2875eOJ5feS4FC9LV8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/QqwGAku7kWk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/2905871213600258623/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2010/10/barajita-premiada-19-cut-paste.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/2905871213600258623?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/2905871213600258623?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/QqwGAku7kWk/barajita-premiada-19-cut-paste.html" title="Barajita premiada (#19) - cut &amp; paste" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2010/10/barajita-premiada-19-cut-paste.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUGSX09cCp7ImA9Wx5VGEU.&quot;"><id>tag:blogger.com,1999:blog-642229783148650277.post-5747092822515049779</id><published>2010-10-12T14:40:00.000+02:00</published><updated>2010-10-12T14:40:28.368+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-12T14:40:28.368+02:00</app:edited><title>Barajita premiada (#18) - sort</title><content type="html">Sort, tan "sencillo" pero tan "poderoso".&lt;br /&gt;
&lt;br /&gt;
El comando sort permite ordenar líneas de un flujo de bytes. Este ordenamiento se puede hacer considerando caracteres ASCII, numéricos, binarios, entre otros.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo:&lt;br /&gt;
&lt;script type="text/javascript" src="http://www.anysportsleague.com/styles/syntaxhighlighter_3.0.83/scripts/shBrushBash.js"&gt;&lt;/script&gt;&lt;pre class="brush: bash"&gt;rodolfo@rcampos-laptop:~/sort$ cat a
hello
1
3
44
4
5
foo
rodolfo@rcampos-laptop:~/sort$ sort a
1
3
4
44
5
foo
hello
rodolfo@rcampos-laptop:~/sort$ sort -n a
foo
hello
1
3
4
5
44
&lt;/pre&gt;&lt;br /&gt;
En el ejemplo mostrado arriba, el archivo "a" fue ordenado en orden alfabético y luego numérico (opción -n). Para ambos casos, puede observar la diferencia por las posiciones de las palabras y los números 4, 5 y 44.&lt;br /&gt;
&lt;br /&gt;
Pero sort también puede ordenar un archivo con líneas con campos separados por algún caracter (Ej. CSV) rápidamente y sin mayores complicaciones. Esto sobre todo me fue de gran utilidad para ordenar un archivo que pesaba 1Gb y estaba separado por "|". Obviamente debido al tamaño, no resultaba trivial abrir el mismo con Excel y pedirle que ordenara las líneas por la columna X. Mire este ejemplo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;rodolfo@rcampos-laptop:~/sort$ cat a
name|id|type
first|3|1
second|1|1
third|2|2
fourth|0|2
rodolfo@rcampos-laptop:~/sort$ sed '1d' a | sort -t '|' -nk 2
fourth|0|2
second|1|1
third|2|2
first|3|1
&lt;/pre&gt;&lt;br /&gt;
En el ejemplo de arriba, es removida la primera línea del archivo con sed (1d) y luego ordenado de forma numérica (-n) considerando el segundo campo (-k 2) para un flujo con campos separados por "|" (opción -t).&lt;br /&gt;
&lt;br /&gt;
&lt;!-- Finally, to actually run the highlighter, you need to include this JS on your page --&gt;&lt;br /&gt;
&lt;script type="text/javascript"&gt;
     SyntaxHighlighter.all()
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/642229783148650277-5747092822515049779?l=camposer-techie.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2dCgmmHQ2GyhXdyeF-YtP6iz1rA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2dCgmmHQ2GyhXdyeF-YtP6iz1rA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2dCgmmHQ2GyhXdyeF-YtP6iz1rA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2dCgmmHQ2GyhXdyeF-YtP6iz1rA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/CosasDeLaTecnologa/~4/IdDXbkNc65A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://camposer-techie.blogspot.com/feeds/5747092822515049779/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://camposer-techie.blogspot.com/2010/10/barajita-premiada-18-sort.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5747092822515049779?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/642229783148650277/posts/default/5747092822515049779?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CosasDeLaTecnologa/~3/IdDXbkNc65A/barajita-premiada-18-sort.html" title="Barajita premiada (#18) - sort" /><author><name>camposer</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://img-fan.theonering.net/rolozo/images/grey/gandalf.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://camposer-techie.blogspot.com/2010/10/barajita-premiada-18-sort.html</feedburner:origLink></entry></feed>

