<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5463615614172154334</id><updated>2010-07-09T16:57:38.381-07:00</updated><title type='text'>Keith's Blog</title><subtitle type='html'>Software etc...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/-/TxtSushi'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/search/label/TxtSushi'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5463615614172154334.post-4400823927153808804</id><published>2010-03-07T13:56:00.000-08:00</published><updated>2010-03-07T13:56:38.055-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='licensing'/><category scheme='http://www.blogger.com/atom/ns#' term='GPL'/><category scheme='http://www.blogger.com/atom/ns#' term='TxtSushi'/><category scheme='http://www.blogger.com/atom/ns#' term='BSD'/><title type='text'>TxtSushi 0.5.1</title><content type='html'>I've just released &lt;a href="http://hackage.haskell.org/package/txt-sushi"&gt;TxtSushi&lt;/a&gt; 0.5.1 on hackage. The only reason for this release was to update the license from GPL to BSD (there are no new features or fixes).&lt;br /&gt;
&lt;br /&gt;
I initially released under GPL because I wasn't really sure where I wanted to go with TxtSushi and I knew it was easier to go from GPL to a more liberal license than to move in the other direction. A recent &lt;a href="http://www.haskell.org/pipermail/haskell-cafe/2010-March/thread.html#74114"&gt;thread on licensing&lt;/a&gt; on haskell cafe convinced me that BSD is the way to go.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5463615614172154334-4400823927153808804?l=blog.keithsheppard.name' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/4400823927153808804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.keithsheppard.name/2010/03/txtsushi-051.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/4400823927153808804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/4400823927153808804'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/2010/03/txtsushi-051.html' title='TxtSushi 0.5.1'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09087715816952529339'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5463615614172154334.post-4361043716084842197</id><published>2009-12-30T17:09:00.000-08:00</published><updated>2010-01-02T09:44:45.209-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TxtSushi'/><title type='text'>TxtSushi 0.5.0</title><content type='html'>&lt;p&gt;
Hiya! I've uploaded TxtSushi 0.5.0 to hackage and there are quite a few changes. I still need to update the documentation on &lt;a href="http://keithsheppard.name/txt-sushi"&gt;http://keithsheppard.name/txt-sushi&lt;/a&gt; which probably won't happen for a week or so (Edit: I have made the updates) but I'll summarize the changes here:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
generalized the JOIN syntax to allow joins on arbitrary expressions (you used to only be able to join on column IDs). &lt;a href="http://patch-tag.com/r/keithshep/txt-sushi/snapshot/hash/20091231012608-b3b23-dbe1eaf2453ae52f300a575889b3376f948cc887/content/pretty/tests/test16.1.bash"&gt;This test script&lt;/a&gt; demonstrates a join on a simple expression
&lt;/li&gt;

&lt;li&gt;
added initial support for the &amp;quot;for x in [col1 .. col4] yield expr&amp;quot; syntax. See this &lt;a href="http://patch-tag.com/r/keithshep/txt-sushi/snapshot/hash/20091221025954-b3b23-24f9d2fd8329e51817b61cc513af04b8376de248/content/pretty/tests/test12.1.bash"&gt;test script&lt;/a&gt; for an example of how it works.
&lt;/li&gt;

&lt;li&gt;
parser now works with UNIX, DOS and Mac newlines no matter which OS you're working on
&lt;/li&gt;

&lt;li&gt;
added integrated help for all SQL functions and operators. Use &amp;quot;tssql -help&amp;quot; to get a list of all functions and operators. Use &amp;quot;tssql -help sum&amp;quot; to get help on the SUM function
&lt;/li&gt;

&lt;li&gt;
added many new function definitions
&lt;/li&gt;

&lt;li&gt;
Grouped data syntax generalization: you can now group tables multiple times (via nested selects) and join those grouped tables to other tables (grouped or not). You can even mix grouped and non-grouped columns in the same expression.
&lt;/li&gt;

&lt;li&gt;
Many bug fixes and code simplifications (still learning how to write good Haskell). Most notably it is now very easy to extend tssql with new SQL functions and operations. Here's an example of what it takes to &lt;a href="http://patch-tag.com/r/keithshep/txt-sushi/snapshot/hash/20091231004744-b3b23-f4ecf1ba0edd45f220abb219bfb45ee6dc243598/patch"&gt;add a new function&lt;/a&gt;. 
&lt;/li&gt;

&lt;li&gt;
added support for bool constants in SQL expressions
&lt;/li&gt;

&lt;li&gt;
improved error messages
&lt;/li&gt;

&lt;li&gt;
&lt;a href="http://code.google.com/p/txt-sushi/issues/detail?id=7&amp;can=1"&gt;Declared&lt;/a&gt; the &amp;quot;classic join&amp;quot; performance bug a feature :-)
&lt;/li&gt;

&lt;li&gt;
and most importantly: changed the synopsis to &amp;quot;The SQL link in your *NIX chain&amp;quot;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Have fun and please send me your &lt;a href="http://code.google.com/p/txt-sushi/issues/list"&gt;bug reports&lt;/a&gt;!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5463615614172154334-4361043716084842197?l=blog.keithsheppard.name' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/4361043716084842197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.keithsheppard.name/2009/12/txtsushi-050.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/4361043716084842197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/4361043716084842197'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/2009/12/txtsushi-050.html' title='TxtSushi 0.5.0'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09087715816952529339'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5463615614172154334.post-9080024345569233544</id><published>2009-10-04T14:39:00.000-07:00</published><updated>2009-10-04T18:12:31.626-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='TxtSushi'/><title type='text'>TxtSushi 0.4.0</title><content type='html'>&lt;p&gt;
I have just uploaded version 0.4.0 of &lt;a href="http://keithsheppard.name/txt-sushi/"&gt;TxtSushi&lt;/a&gt; with the following changes:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
General code improvements: fixed any -Wall warnings, improved help messages and
SQL parser error messages
&lt;/li&gt;
&lt;li&gt;
External sort: added an -external-sort option to tssql which tells tssql to
sort on disk for JOIN and ORDER BY. This was tested on a 10G CSV file and it
worked but it took 10 hours on my macbook! I think that this can be improved.
&lt;/li&gt;
&lt;li&gt;
Nested select: TxtSushi now allows nested select statements
&lt;/li&gt;
&lt;li&gt;
Classic joins: added support for older style join syntax. These joins are still
unoptimized though so their time complexity is row_count^2 rather than the
row_count(log row_count) complexity when using the INNER JOIN syntax
&lt;/li&gt;
&lt;li&gt;
Transpose utilities: added transposecsv and transposetab utilities which will
print a transposed version of the given table
&lt;/li&gt;
&lt;/ul&gt;

&lt;b&gt;&lt;u&gt;Fellow Haskell Hackers Wanted:&lt;/u&gt;&lt;/b&gt;

&lt;p&gt;
I think TxtSushi fills a unique niche in the *NIX toolchain for tabular data. On one side you have python, perl, sed, awk which are all great for general purpose text processing but it takes a lot of hand rolled code to do table filtering/joining/transformation and it gets even worse if you want to be able to deal correctly with quoted fields. On the other side you have real databases which allow you to do all of these things but which tend to be heavyweight solutions that require data import/export and don't want anything to do with your other *NIX commands. TxtSushi is different because it takes your text tables (or event STDIN) as they are and doesn't want to be anything more than an SQL link in your *NIX tool chain.
&lt;/p&gt;

&lt;p&gt;
The two long term goals that I have for TxtSushi are to improve it to the point where it is generally available on *NIX distro package managers and that it is "owned" and developed by a group instead of just me. These two goals really go together since I may not be able to do all of the work required to mature TxtSushi by myself. I thought about keeping these goals to myself until I could get to the point where the core architecture are solidified and the remaining work would amount to developing and integrating modules into the existing architecture, but I think things are just moving too slowly with me hacking alone. So, if you are interested in hacking TxtSushi with me let me know!
&lt;/p&gt;

&lt;p&gt;
Off the top of my head here are some relatively self-contained contributions that can be made:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Extensible SQL Functions: This one should be fun. The way I implemented SQL functions isn't very pretty. The function parsers are in SQLParser.hs toward the bottom and the SQL Function execution code is in a big function guard toward the bottom of SQLExecution. I think we should have an SQLFunction type which would bundle up both the parsing and execution for a single SQL function/operator. The real payoff is that we could then have an XMonad-like configuration file that allows users to define their own SQL functions (Eg: if a user wants to define a STD_DEV aggregate function, now they can as long as they know haskell).
&lt;/li&gt;
&lt;li&gt;
Improve table parsing: the table parsing code was the first thing I wrote and it shows. It should be replaced by something more like what you find in &lt;a href="http://book.realworldhaskell.org/read/using-parsec.html"&gt;Real World Haskell: Using Parsec&lt;/a&gt; which is much more concise and tolerant of any end-of-line encoding
&lt;/li&gt;
&lt;li&gt;
External sort: The external sort algorithm works but could probably use a more expert Haskell hacker's eye to become efficient (there were a couple of reasons I couldn't just use the external-sort cabal library as-is).
&lt;/li&gt;
&lt;li&gt;
Efficient classic joins: The classic style WHERE joins should be just as efficient as the INNER JOIN joins. If you're interested in this I have an idea for what I think may be the easiest way to do this. See &lt;a href="http://code.google.com/p/txt-sushi/issues/detail?id=7"&gt;issue 7&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Support for SQL Case Statement: See &lt;a href="http://code.google.com/p/txt-sushi/issues/detail?id=8"&gt;issue 8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Implement window functions like RANK() and ROW_NUMBER(): See &lt;a href="http://code.google.com/p/txt-sushi/issues/detail?id=11"&gt;issue 11&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Test cases? Bug reports? Some other idea you have? ...
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
If you're curious, the simplest way to browse the source is here &lt;a href="http://patch-tag.com/r/keithshep/txt-sushi"&gt;http://patch-tag.com/r/keithshep/txt-sushi&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5463615614172154334-9080024345569233544?l=blog.keithsheppard.name' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/9080024345569233544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.keithsheppard.name/2009/10/txtsushi-040.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/9080024345569233544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/9080024345569233544'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/2009/10/txtsushi-040.html' title='TxtSushi 0.4.0'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09087715816952529339'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5463615614172154334.post-4593499907622283463</id><published>2009-06-19T18:24:00.000-07:00</published><updated>2009-06-19T18:32:34.186-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='flat file'/><category scheme='http://www.blogger.com/atom/ns#' term='TxtSushi'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>MySQL responds to the threat ...</title><content type='html'>... posed by TxtSushi's foray into the database market.

&lt;a href="http://dev.mysql.com/tech-resources/articles/csv-storage-engine.html"&gt;http://dev.mysql.com/tech-resources/articles/csv-storage-engine.html&lt;/a&gt;

In all seriousness, this looks like a really nice solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5463615614172154334-4593499907622283463?l=blog.keithsheppard.name' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/4593499907622283463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.keithsheppard.name/2009/06/mysql-responds-to-threat.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/4593499907622283463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/4593499907622283463'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/2009/06/mysql-responds-to-threat.html' title='MySQL responds to the threat ...'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09087715816952529339'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5463615614172154334.post-1192615190536412718</id><published>2009-06-18T19:13:00.000-07:00</published><updated>2009-06-18T19:46:15.507-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flat file'/><category scheme='http://www.blogger.com/atom/ns#' term='TxtSushi'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>HaExcel</title><content type='html'>I stumbled upon &lt;a href="http://haskell.di.uminho.pt/jacome/index.html"&gt;HaExcel&lt;/a&gt; today and thought "Wow! This sounds just like TxtSushi." After looking more closely it has important differences. It handles import/export between spreadsheet and database rather than directly performing queries on a set of spreadsheets.

If you're looking to bridge spreadsheets and databases you should give it a look.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5463615614172154334-1192615190536412718?l=blog.keithsheppard.name' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/1192615190536412718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.keithsheppard.name/2009/06/haexcel.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/1192615190536412718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/1192615190536412718'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/2009/06/haexcel.html' title='HaExcel'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09087715816952529339'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5463615614172154334.post-8419609512948923138</id><published>2009-05-31T19:17:00.001-07:00</published><updated>2009-05-31T19:51:56.481-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='flat file'/><category scheme='http://www.blogger.com/atom/ns#' term='TxtSushi'/><title type='text'>TxtSushi 0.3.0</title><content type='html'>Just released TxtSushi 0.3.0 which adds:
&lt;ul&gt;&lt;li&gt;Improved SQL parsing and error reporting&lt;/li&gt;&lt;li&gt;GROUP BY ... HAVING support with several aggregate functions (see home page)&lt;/li&gt;&lt;li&gt;A little utility "namecolumns" which will add sequential column names to a table which is useful if your flat file doesn't have a header with column names.
&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5463615614172154334-8419609512948923138?l=blog.keithsheppard.name' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/8419609512948923138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.keithsheppard.name/2009/05/txtsushi-030.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/8419609512948923138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/8419609512948923138'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/2009/05/txtsushi-030.html' title='TxtSushi 0.3.0'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09087715816952529339'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5463615614172154334.post-6705281947940500198</id><published>2009-05-21T20:20:00.000-07:00</published><updated>2009-05-21T20:44:23.717-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='flat file'/><category scheme='http://www.blogger.com/atom/ns#' term='TxtSushi'/><title type='text'>TxtSushi 0.2</title><content type='html'>I just released &lt;a href="http://keithsheppard.name/txt-sushi"&gt;TxtSushi&lt;/a&gt; 0.2 with the following updates:
&lt;ol&gt;&lt;li&gt;Improved type coercion. Some of the rules I was using before did not make sense. At some point I will write down what the rules are.&lt;/li&gt;&lt;li&gt;Added some extra functions/operators including a regex matcher. Here is the full list: SUBSTRING, UPPER, LOWER, TRIM, *, /, +, - (binary and unary), =,                     &lt;&gt; (not equal test), &lt;, &lt;=, &gt;, &gt;=, AND, OR, || (string concatination),                     =~ (regex matching)                 &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/5463615614172154334-6705281947940500198?l=blog.keithsheppard.name' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/6705281947940500198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.keithsheppard.name/2009/05/txtsushi-02.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/6705281947940500198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/6705281947940500198'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/2009/05/txtsushi-02.html' title='TxtSushi 0.2'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09087715816952529339'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5463615614172154334.post-2687613405440548447</id><published>2009-05-16T19:08:00.000-07:00</published><updated>2009-05-16T19:38:40.549-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='flat file'/><category scheme='http://www.blogger.com/atom/ns#' term='bioinformatics'/><category scheme='http://www.blogger.com/atom/ns#' term='spreadsheet'/><category scheme='http://www.blogger.com/atom/ns#' term='TxtSushi'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Yay! TxtSushi 0.1</title><content type='html'>I just released my first haskell application called &lt;a href="http://keithsheppard.name/txt-sushi"&gt;TxtSushi&lt;/a&gt;. It's basically useful for processing comma-delimited tables with SQL select statements, plus some other small conversion and formatting utilities. Here's an example that I just tried out with real data and ... it works!
&lt;pre&gt;wget -q -O - ftp://ftp.informatics.jax.org/pub/reports/MRK_List2.rpt | tabtocsv - \
| tssql -table mgi - \
'select `MGI Accession ID`, Symbol, Chr, trim(`cM Position`)
from mgi where (Chr = 1 or Chr = 8 or Chr = 19) and trim(`cM Position`) = "N/A"
order by Chr+0, Symbol' \
| csvtopretty -&lt;/pre&gt;
Which gives you:
&lt;pre&gt;MGI Accession ID|Symbol                     |Chr|TRIM(cM Position)
MGI:3829209     |100039643                  |1  |N/A
MGI:3823247     |100042382                  |1  |N/A
MGI:3826364     |665246                     |1  |N/A
MGI:3828086     |667118                     |1  |N/A
MGI:3829949     |Bmd5a                      |1  |N/A
MGI:3829954     |Bmd5b                      |1  |N/A
MGI:3829959     |Bmd5c                      |1  |N/A
MGI:3762525     |Drinkcacl24                |1  |N/A
MGI:3762526     |Drinkmgcl21                |1  |N/A
MGI:3762535     |Drinkmgcl24                |1  |N/A
MGI:3762388     |Drinksac5                  |1  |N/A
MGI:3836959     |Mir1927                    |1  |N/A
MGI:3836960     |Mir1928                    |1  |N/A
MGI:3837225     |Mir1981                    |1  |N/A
MGI:98018       |OTTMUSG00000002279         |1  |N/A
MGI:3840135     |OTTMUSG00000020948         |1  |N/A
MGI:3834078     |OTTMUSG00000026591         |1  |N/A
MGI:3826770     |Qrr1                       |1  |N/A
MGI:3826773     |Qrr1d                      |1  |N/A
MGI:3826772     |Qrr1p                      |1  |N/A
MGI:3844119     |Sfp1                       |1  |N/A
MGI:3832320     |T(1E2.1;8B1.2)2Lub         |1  |N/A
MGI:3843694     |Tg(tetO-Chrnb2*V287L)H3Gica|1  |N/A
MGI:3720916     |Tgq9                       |1  |N/A
MGI:3640786     |lrm1                       |1  |N/A
MGI:3822907     |384645                     |8  |N/A
MGI:1924337     |Ankrd11                    |8  |N/A
MGI:3844136     |Arrh1                      |8  |N/A
MGI:3705791     |Defa-ps3                   |8  |N/A
MGI:3837211     |Mir1966                    |8  |N/A
MGI:3837213     |Mir1967                    |8  |N/A
MGI:3837215     |Mir1968                    |8  |N/A
MGI:3837216     |Mir1969                    |8  |N/A
MGI:3833469     |OTTMUSG00000016477         |8  |N/A
MGI:3833836     |OTTMUSG00000031120         |8  |N/A
MGI:3844123     |Sfp3                       |8  |N/A
MGI:3628904     |T(Tp(1E2.1);8B1.2)2Lub     |8  |N/A
MGI:3720925     |Tgq18                      |8  |N/A
MGI:3640782     |gpg6                       |8  |N/A
MGI:88396       |Chrm1                      |19 |N/A
MGI:3762554     |Drinkqhcl2                 |19 |N/A
MGI:3762516     |Drinksac2                  |19 |N/A
MGI:3720096     |Hdlq59                     |19 |N/A
MGI:3837023     |Mir1950                    |19 |N/A
MGI:1914960     |Polr2g                     |19 |N/A
MGI:3843453     |Prdt5                      |19 |N/A
MGI:3828068     |Tgq29                      |19 |N/A&lt;/pre&gt;
I created this because it is something that will be useful to my work (flat files are just about everywhere you turn in bioinformatics), but I'm really hoping that this will be something that is generally useful to other people.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5463615614172154334-2687613405440548447?l=blog.keithsheppard.name' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.keithsheppard.name/feeds/2687613405440548447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.keithsheppard.name/2009/05/yay-txtsushi-01.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/2687613405440548447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5463615614172154334/posts/default/2687613405440548447'/><link rel='alternate' type='text/html' href='http://blog.keithsheppard.name/2009/05/yay-txtsushi-01.html' title='Yay! TxtSushi 0.1'/><author><name>Keith</name><uri>http://www.blogger.com/profile/04421311170476011799</uri><email>keithshep@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09087715816952529339'/></author><thr:total>0</thr:total></entry></feed>