{"id":326,"date":"2018-07-24T09:02:31","date_gmt":"2018-07-24T12:02:31","guid":{"rendered":"http:\/\/suspensao.blog.br\/descrenca\/?p=326"},"modified":"2018-07-24T09:02:31","modified_gmt":"2018-07-24T12:02:31","slug":"trocando-figurinhas-sobre-o-terminal","status":"publish","type":"post","link":"https:\/\/suspensao.blog.br\/descrenca\/trocando-figurinhas-sobre-o-terminal\/","title":{"rendered":"Trocando figurinhas sobre o terminal"},"content":{"rendered":"<p>Uma das minhas divers\u00f5es nesta Copa foi montar um \u00e1lbum de figurinhas. Na verdade, montei o \u00e1lbum porque me filho queria muito, mas me diverti tamb\u00e9m, eu acho.<\/p>\n<div id=\"attachment_333\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-333\" data-attachment-id=\"333\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/trocando-figurinhas-sobre-o-terminal\/img_20180716_090001719\/\" data-orig-file=\"https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719.jpg?fit=2592%2C1456&amp;ssl=1\" data-orig-size=\"2592,1456\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;XT1032&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1039348800&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.5&quot;,&quot;iso&quot;:&quot;800&quot;,&quot;shutter_speed&quot;:&quot;0.1&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"IMG_20180716_090001719\" data-image-description=\"\" data-image-caption=\"&lt;p&gt;Infelizmente, n\u00e3o completei ainda&lt;\/p&gt;\n\" data-medium-file=\"https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719.jpg?fit=300%2C169&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719.jpg?fit=1024%2C575&amp;ssl=1\" class=\"size-medium wp-image-333\" src=\"https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719-300x169.jpg?resize=300%2C169\" alt=\"\u00c1lbum de figurinhas da Copa do Mundo de 2018, aberto na p\u00e1gina da Fran\u00e7a, com tr\u00eas figurinhas faltando\" width=\"300\" height=\"169\" srcset=\"https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719.jpg?resize=300%2C169&amp;ssl=1 300w, https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719.jpg?resize=768%2C431&amp;ssl=1 768w, https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719.jpg?resize=1024%2C575&amp;ssl=1 1024w, https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2018\/07\/IMG_20180716_090001719.jpg?w=2000&amp;ssl=1 2000w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-333\" class=\"wp-caption-text\">Infelizmente, n\u00e3o completei ainda<\/p><\/div>\n<p>Parte importante de colecionar figurinhas \u00e9 trocar as repetidas. Atrav\u00e9s de mensagens em grupos de WhatsApp, dizemos quais repetidas temos e quais figurinhas ainda precisamos. Como programador, me recusei a ficar comparando as listas, ent\u00e3o escrevi um <a href=\"https:\/\/pastebin.com\/FLDz684P\">programinha<\/a> em Python (com <a href=\"http:\/\/suspensao.blog.br\/descrenca\/doctest\/\">doctests e tudo<\/a>) para encontrar intersec\u00e7\u00f5es.<\/p>\n<h3>O laptop sumido<\/h3>\n<p>Semana passada vieram \u00e0 minha casa para trocar figurinhas. Eu tinha as listas de repetidas e necess\u00e1rias, tanto minhas quanto da outra colecionadora, mas o meu script estava em um outro laptop. Eu nem sabia onde esse laptop estava, e a visita estava com pressa.<\/p>\n<p>N\u00e3o daria tempo de achar o computador, ou de reescrever o programa. Ou mesmo de comparar manualmente.<\/p>\n<p>Hora de usar alguns comandos Unix!<\/p>\n<h3>O formato das listas<\/h3>\n<p>As listas geralmente t\u00eam esse formato:<\/p>\n<p><code>15, 18, 26, 31, 40, 45 (2), 49, 51, 110, 115, 128, 131 (2), 143, 151, 161, 162, 183 (2), 216 (2), 221, 223, 253, 267 (3), 269, 280, 287, 296, 313, 325, 329, 333 (2), 353 (3), 355, 357, 359, 362, 365, 366, 371, 373, 384, 399, 400, 421 (2), 445, 457, 469, 470, 498 (2), 526, 536, 553, 560, 568, 570, 585, 591 (2), 604 (2), 639 (2), 660.<\/code><\/p>\n<p>Basicamente, eu precisava remover tudo que n\u00e3o fossem d\u00edgitos, al\u00e9m dos n\u00fameros entre par\u00eanteses, e comparar duas listas. F\u00e1cil at\u00e9.<\/p>\n<h3>Preprocessando com sed<\/h3>\n<p>Primeiro, preciso remover os contadores entre par\u00eanteses:<\/p>\n<p><code>$ cat list.txt | sed 's\/([^)]*)\/\/g'<br \/>\n15, 18, 26, 31, [...] 591 , 604 , 639 , 660.<\/code><\/p>\n<p>(Eu sei, <a href=\"http:\/\/porkmail.org\/era\/unix\/award.html\">UUOC<\/a>. Que seja.)<\/p>\n<p>Depois, coloco cada n\u00famero em uma linha:<\/p>\n<p><code>$ cat list.txt | sed 's\/([^)]*)\/\/g' | sed 's\/, *\/\\n\/g'<\/code><\/p>\n<p>Depois, limpo cada linha de qualquer caractere que n\u00e3o seja um d\u00edgito:<\/p>\n<p><code>cat list.txt | sed 's\/([^)]*)\/\/g' | sed 's\/, *\/\\n\/g' | sed 's\/[^0-9]*\\([0-9]*\\)[^0-9]*\/\\1\/g'<\/code><\/p>\n<p>(Na pr\u00e1tica chamo <code>sed<\/code> apenas uma vez, passando duas express\u00f5es. Aqui acho que fica mais claro invocar <code>sed<\/code> v\u00e1rias vezes.)<\/p>\n<p>Por fim, ordeno os valores:<\/p>\n<p><code>$ cat list.txt | sed 's\/([^)]*)\/\/g' | sed 's\/, *\/\\n\/g' | sed 's\/[^0-9]*\\([0-9]*\\)[^0-9]*\/\\1\/g' | sort -n &gt; mine-needed.txt<\/code><\/p>\n<p>Fa\u00e7o isso com a lista de figuras necess\u00e1rias, e tamb\u00e9m com a lista de figuras repetidas, conseguindo dois arquivos.<\/p>\n<h3>Encontrando intersec\u00e7\u00f5es com grep<\/h3>\n<p>Agora, preciso compar\u00e1-los. H\u00e1 muitas op\u00e7\u00f5es, e eu escolhi <a href=\"https:\/\/stackoverflow.com\/a\/27960271\/287976\">usar <code>grep<\/code><\/a>.<\/p>\n<p>No caso, chamei <code>grep<\/code> passando um dos arquivos como entrada, e o outro arquivo como uma lista de padr\u00f5es para casar, atrav\u00e9s da op\u00e7\u00e3o <code>-f<\/code>. Al\u00e9m disso, apenas o matching completo das linhas importa, ent\u00e3o usaremos a <em>flag<\/em> <code>-x<\/code>. Por fim, pedi para <code>grep<\/code> comparar strings diretamente (ao inv\u00e9s de consider\u00e1-las express\u00f5es regulares) com a <em>flag<\/em> <code>-F<\/code>.<\/p>\n<p><code>$ fgrep -Fxf mine-needed.txt theirs-repeated.txt<br \/>\n253<br \/>\n269<br \/>\n333<br \/>\n470<br \/>\n639<\/code><\/p>\n<p>Pronto! Em um minuto, j\u00e1 sei quais figuras quero. Basta fazer o mesmo com as minhas repetidas.<\/p>\n<h3>Por que isto \u00e9 interessante?<\/h3>\n<p>Para mim, hoje, estes one-liners n\u00e3o s\u00e3o grande coisa. O interessante \u00e9 que, quando comecei a usar o terminal, eles seriam incr\u00edveis. S\u00e9rio, olhe quantos pipes usamos para preprocessar os arquivos! E esse truque com o <code>grep<\/code>? Eu penava s\u00f3 para fazer uma regex que funcionasse! Na verdade, at\u00e9 solucionar esse problema, eu nem conhecia a op\u00e7\u00e3o <code>-x<\/code>.<\/p>\n<p>Certa vez ajudei um amigo meu a processar um bom n\u00famero de arquivos. Ele j\u00e1 levava mais de duas horas tentando fazer isso com Java, e resolvemos juntos em dez minutos com shell script. Ele ent\u00e3o me falou o quanto queria saber shell script e me perguntou como aprender.<\/p>\n<p>Pois bem, pequenos exemplos como estes, por simples que sejam, me ensinaram muito. \u00c9 assim que se aprende: tentando resolver problemas, conhecendo comandos e op\u00e7\u00f5es aos poucos. E, no final, esta \u00e9 uma habilidade muito valiosa.<\/p>\n<p>Ent\u00e3o, espero que esta pequena brincadeira enrique\u00e7a seu dia, tamb\u00e9m. Certamente enriqueceu o meu &#8211; queria ter pensado nela antes de gastar tanto tempo no script Python que escrevi!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Uma das minhas divers\u00f5es nesta Copa foi montar um \u00e1lbum de figurinhas. Na verdade, montei o \u00e1lbum porque me filho queria muito, mas me diverti tamb\u00e9m, eu acho. Parte importante de colecionar figurinhas \u00e9 trocar as repetidas. Atrav\u00e9s de mensagens em grupos de WhatsApp, dizemos quais repetidas temos e quais figurinhas ainda precisamos. Como programador, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[27,1],"tags":[89,90,91],"class_list":["post-326","post","type-post","status-publish","format-standard","hentry","category-shell-script","category-uncategorized","tag-grep","tag-sed","tag-shell-script"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23QLV-5g","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/326","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/comments?post=326"}],"version-history":[{"count":10,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/326\/revisions"}],"predecessor-version":[{"id":338,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/326\/revisions\/338"}],"wp:attachment":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/media?parent=326"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/categories?post=326"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/tags?post=326"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}