Como usar o GVim para tudo – Parte 1
Olá!
Os poucos que já me conhecem, sabem que sou fã do GVim. Nem Vi nem Vim. Sempre escuto pessoas falando de outros editores, como o bluefish, notepad++, emacs. Mas, eu sou cabeça-dura, ranzinza mesmo. Então vou fazer um série de posts mostrando umas coisas divertidas de se fazer usando o GVim para facilitar a vida e acelerar o desenvolvimento. São coisas pequenas mas, que às vezes, consomem um bom tempo e enchem o saco.
Começando por criar uma SQL de INSERT numa tabela que tenha muitas colunas. No exemplo abaixo, vou usar o PHP e MySQL para fazer, porém, é só adaptar pra outras linguagens.
Bom, vamos começar do começo:
Listando as colunas.
Vamos imaginar uma tabela do banco de dados que tenha muitas colunas. Como exemplo, vou usar uma própria do wordpress, que é responsável pelo armazenamento dos posts. A idéia do post não é ensinar expressão regular, mas sim mostrar como utilizá-la no GVim e mostrar o seu real poder.
Criando à partir do terminal:
Bom, tudo começa no conhecido terminal. Digitamos:
# mysql -uUSER -pSENHA DATABASE -e “describe TABLE;” #No meu caso usei a tabela de posts wordpress
+-----------------------+---------------------+------+-----+---------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------------------+---------------------+------+-----+---------------------+----------------+ | ID | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | post_author | bigint(20) | NO | | 0 | | | post_date | datetime | NO | | 0000-00-00 00:00:00 | | | post_date_gmt | datetime | NO | | 0000-00-00 00:00:00 | | | post_content | longtext | NO | | NULL | | | post_title | text | NO | | NULL | | | post_category | int(4) | NO | | 0 | | | post_excerpt | text | NO | | NULL | | | post_status | varchar(20) | NO | | publish | | | comment_status | varchar(20) | NO | | open | | | ping_status | varchar(20) | NO | | open | | | post_password | varchar(20) | NO | | | | | post_name | varchar(200) | NO | MUL | | | | to_ping | text | NO | | NULL | | | pinged | text | NO | | NULL | | | post_modified | datetime | NO | | 0000-00-00 00:00:00 | | | post_modified_gmt | datetime | NO | | 0000-00-00 00:00:00 | | | post_content_filtered | text | NO | | NULL | | | post_parent | bigint(20) | NO | MUL | 0 | | | guid | varchar(255) | NO | | | | | menu_order | int(11) | NO | | 0 | | | post_type | varchar(20) | NO | MUL | post | | | post_mime_type | varchar(100) | NO | | | | | comment_count | bigint(20) | NO | | 0 | | +-----------------------+---------------------+------+-----+---------------------+----------------+
Deve aparecer algo parecido com isso para você. Bom, para facilitar, apagamos manualmente as 3 primeras linhas e a última. Ou, se quiser fazer pelo gvim digitando:
:1,3g/^./d :$g/^./d
Bom, o comando g, vai fazer um busca e, logo após, executa um comando. No nosso caso as três primeiras linhas que contenham pelo menos 1 caracter e a última linha do arquivo.
Jogando o lixo no lixo
:%s/^|s*([^ ]*).*/1/g
Você obterá algo assim:
ID post_author post_date post_date_gmt post_content post_title post_category post_excerpt post_status comment_status ping_status post_password post_name to_ping pinged post_modified post_modified_gmt post_content_filtered post_parent guid menu_order post_type post_mime_type comment_count
“It’s like magic!” Wow. Sim. Usamos o %s, que substitui no arquivo inteiro. Notem que é necessário escapar os parênteses para criar grupos em expressão regular. Isso é devido a utilidade do GVim. Em um editor cuja finalidade é facilitar a vida na programação, não teria sentido ao contrário. Afinal, procurar por um if ( ou um while () é muito comum. E ter que ficar escapando tudo, ia ser um saco! Bom, uma explicação melhor:
- %s -> substitui em todo arquivo.
- /^|s*([^ ]*).*/ -> Começa com | pode ter espaços (captura tudo que não for espaços) o resto da linha que não nos interessa.
- 1/g -> 1 Faz uma referência ao primeiro grupo capturado na expressão anterior, no caso (tudo que não for espaço). O g é para que pudesse casar mais de uma vez. Neste caso não é necessário (força do hábito).
Notem que é necessário aquele .* do final, pois a expressão que casar, é a expressão substituída. E não somente o que estiver entre os grupos. Colocando o que queremos manter no grupo (no caso o nome da coluna) e substituimos a linha inteira pelo nome da coluna.
Juntando numa única linha
Bom, agora é simples! Para montarmos a SQL precisamos juntar elas em 1 linha só. Para isso, olhamos o número de linhas que tem no arquivo e, no modo normal, com o ponteiro na primeira coluna da primeira linha (pra ter certeza pode ser digitado gg), digitamos:
(NUMERO_DE_LINHAS)J – Por exemplo: O arquivo tem 24 linhas, então será digitado: 24J. Tendo elas em uma só linha, basta substituir os espaços por vírgula:
%s/s/, /g
Colocar o digitado entre parênteses e depois digitar: yypp. Agora temos duas linhas iguais, assim:
(ID, post_author, post_date, post_date_gmt, post_content, post_title, post_category, post_excerpt, post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_content_filtered, post_parent, guid, menu_order, post_type, post_mime_type, comment_count) (ID, post_author, post_date, post_date_gmt, post_content, post_title, post_category, post_excerpt, post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_content_filtered, post_parent, guid, menu_order, post_type, post_mime_type, comment_count) (ID, post_author, post_date, post_date_gmt, post_content, post_title, post_category, post_excerpt, post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_content_filtered, post_parent, guid, menu_order, post_type, post_mime_type, comment_count)
Dando forma
Bom, digitamos manualmente INSERT INTO e VALUES, no começo da primeira linha e ao final, respectivamente.
Na linha de baixo, vamos utilizar uma coisinha legal:
:2s/([^,]*)[,]?/'%s', /g
O que acaba na seguinte transformação linha 2:
'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s',
Basta ajustar os detalhes, parênteses e vírgulas a mais! (Poderia ser feito um grupo na vírgula, pra se caso ela existir, colocar, e não por, caso contrário. Mas eu achei muita frescura) E agora o toque final:
:3s/([^,()]*)[,]?/addslashes($_POST['1']), /g
O que retorna:
addslashes($_POST['(ID']), addslashes($_POST['post_author']), addslashes($_POST['post_date']), addslashes($_POST['post_date_gmt']), addslashes($_POST['post_content']), addslashes($_POST['post_title']), addslashes($_POST['post_category']), addslashes($_POST['post_excerpt']), addslashes($_POST['post_status']), addslashes($_POST['comment_status']), addslashes($_POST['ping_status']), addslashes($_POST['post_password']), addslashes($_POST['post_name']), addslashes($_POST['to_ping']), addslashes($_POST['pinged']), addslashes($_POST['post_modified']), addslashes($_POST['post_modified_gmt']), addslashes($_POST['post_content_filtered']), addslashes($_POST['post_parent']), addslashes($_POST['guid']), addslashes($_POST['menu_order']), addslashes($_POST['post_type']), addslashes($_POST['post_mime_type']), addslashes($_POST['comment_count)']),
E, para concluir tudo, colocamos dentro de um sprintf, tudo termina assim:
$insertSQL = sprintf("INSERT INTO (ID, post_author, post_date, post_date_gmt, post_content, post_title, post_category, post_excerpt, post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_content_filtered, post_parent, guid, menu_order, post_type, post_mime_type, comment_count) VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",addslashes($_POST['ID']), addslashes($_POST['post_author']), addslashes($_POST['post_date']), addslashes($_POST['post_date_gmt']), addslashes($_POST['post_content']), addslashes($_POST['post_title']), addslashes($_POST['post_category']), addslashes($_POST['post_excerpt']), addslashes($_POST['post_status']), addslashes($_POST['comment_status']), addslashes($_POST['ping_status']), addslashes($_POST['post_password']), addslashes($_POST['post_name']), addslashes($_POST['to_ping']), addslashes($_POST['pinged']), addslashes($_POST['post_modified']), addslashes($_POST['post_modified_gmt']), addslashes($_POST['post_content_filtered']), addslashes($_POST['post_parent']), addslashes($_POST['guid']), addslashes($_POST['menu_order']), addslashes($_POST['post_type']), addslashes($_POST['post_mime_type']), addslashes($_POST['comment_count']));
Ah, vamos, não foi tão difícil nem demorado! Garanto que você perderia mais tempo tendo que fazer isso manualmente!
Copiando do phpMyAdmin:
Bom, para aqueles que trabalham com o phpMyAdmin, basta ir na tabela deseja e, da aba Estrutura, copiar a tabela para o GVim, vai ficar algo mais ou menos assim:
ID bigint(20) UNSIGNED Não auto_increment Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_author bigint(20) Não 0 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_date datetime Não 0000-00-00 00:00:00 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_date_gmt datetime Não 0000-00-00 00:00:00 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_content longtext utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_title text utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_category int(4) Não 0 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_excerpt text utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_status varchar(20) utf8_general_ci Não publish Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo comment_status varchar(20) utf8_general_ci Não open Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo ping_status varchar(20) utf8_general_ci Não open Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_password varchar(20) utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_name varchar(200) utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo to_ping text utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo pinged text utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_modified datetime Não 0000-00-00 00:00:00 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_modified_gmt datetime Não 0000-00-00 00:00:00 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_content_filtered text utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_parent bigint(20) Não 0 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo guid varchar(255) utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo menu_order int(11) Não 0 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_type varchar(20) utf8_general_ci Não post Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo post_mime_type varchar(100) utf8_general_ci Não Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo comment_count bigint(20) Não 0 Navegador distingue valores Alterar Eliminar Primária Único Índice Texto completo
Vamos remover o que não nos é necessário e pegar somente a primeira coluna dessa tabela separada por tabs, digitando no GVim:
:%s/s*([^ t]*).*/1/g
Bom, conseguimos o que queríamos. Uma coluna em cada linha. Agora é só concluir como descrito acima, onde os dados provém do terminal. o/
Conclusão
Idéias, sugestões, receitas de bolos e muito mais, vocês podem me mandar por e-mail ou comentar abaixo!
E lembrem-se: mais dicas de coisas que podem ser feitas no GVim estão por vir!
Posts Relacionados
Por favor, se você deseja opinar, criticar ou até mesmo mandar uma receita de bolo, deixe um comentário! Ou fique atento aos feeds.
Comentários
o/
Tu se referes a uma função que executa todos os comandos?
Pois a questão não é decorar os comandos, porque só usei 2 distintos: :s/ e :g/. A idéia do post é ver que usando substituição (:s/) com expressão regular da pra fazer muita coisa! Em breve terá coisas para se usar o vimrc, plugins e atalhos. Pode deixar ;P





fácinho de decorar os comandos….
Porque tu não coloca no fim uns maps exemplo para inserir no vimrc que fazem tudo isso ai? pro pessoal que gostou copiar e colar?
=D