Vim: fun with filters

Vim lets you pipe text through an external filter. There are some obviously nice ways to use this in Linux, like

:!sort | uniq

which will sort all your lines, and then get rid of duplicate lines. But you can do things that are much more sophisticated if you write your own scripts which read from STDIN and output something back to STDOUT.

For example I wrote this Ruby script.

#!/usr/bin/ruby
 
del = %r{#{Regexp.escape ARGV[0]}} if ARGV[0]
del ||= %r{\s+}
STDIN.each do |line|
    puts '(' + line.strip.gsub(/'/, "''").split(del,-1).collect{|x| "'#{x}'"}.join(',') + '),'
end

This will take a line full of delimited fields, escape all the single-quotes, split into fields on the delimiter, wrap each field in single-quotes, put commas between the fields, wrap each line in (), and put a comma at the end of the line. You can either specify a delimiter, or don't specify one and it'll default to splitting on whitespace. I use this to turn a delimited ASCII file of data into a form suitable for an INSERT command in SQL. So if I start with this:

bob|2|3|Some description
chester|1|4|Another description
sarah|99|0|Let's try an apostrophe

and run this in Vim:

:%!sql_wrap.rb '|'

I get this:

('bob','2','3','Some description'),
('chester','1','4','Another description'),
('sarah','99','0','Let''s try an apostrophe'),

Or consider another simple example. This script will HTML-escape text:

#!/usr/bin/ruby
 
require 'cgi'
 
STDIN.each do |line|
    puts CGI::escapeHTML(line)
end

So it'll turn this:

Is 5 > 3?  Yes, & isn't that neat?

into this:

Is 5 > 3?  Yes, & isn't that neat?
Tags: , , ,

Leave a Reply

You can use these tags in comments (Note: HTML is automatically escaped inside <pre> tags, nowhere else, so if you post source code, put it in <pre>):

<pre lang="some_programming_language"> 
<em>
<strong>
<a href="url">

NOTE: Comments are automatically spam-filtered. If your comment fails to appear, it was likely munched by the filter. Try not to link-spam or post anything that looks like it was typed by a robot.