terminal-window viewer for tab-delimited files in *nix?

5

4

I work with a lot of tab-delimited data files, with varying columns of uncertain length.

Typically, the way people view these files is to bring them down from the server to their Windows or Mac machine, and then open them up in Excel. This is certainly fully-featured, allowing filtering and other nice options. But sometimes, you just want to look at something quickly on the command line.

I wrote a bare-bones utility to display the first<n>lines of a file like so:

--- line 1 ---
1:{header-1} 2:{header-2} 3:...

--- line 2 ---
1:{data-1} 2:{data-2} 3:...

This is, obviously, very lame, but it's enough to pipe through grep, or figure out which header columns to use "cut -f" on.

Is there a *nix-based viewer for a terminal session which will display rows and columns of a tab-delimited file and let you move the viewing window over the file, or otherwise look at data?

I don't want to write this myself; instead, I'd just make a reformatter which would replace tabs with spaces for padding so I could open the file up in emacs and see aligned columns. But if there's already a tool out there to do something like this, that'd be great!

(Or, I could just live with Excel.)

Michael H.

Posted 2010-05-11T20:16:24.170

Reputation: 341

Answers

7

There is a Unix text-mode spreadsheet called sc which may work for your use. You will probably need to pass the file through psc to convert it to the file format that sc uses.

Paused until further notice.

Posted 2010-05-11T20:16:24.170

Reputation: 86 075

psc doesn't like columns with more than 1021 characters in them. That's a problem for me. I'd like something really robust for viewing (not editing) delimited files like this. I have made my own scripts, but they're not ideal. – Aaron McDaid – 2015-07-10T10:40:00.963

That sounds very promising! It seems to have led me down the rabbit-hole of figuring out where to get sc, and why my Fedora installation isn't seeing all package upgrades, but that's not anyone else's problem. Thanks! – Michael H. – 2010-05-12T18:48:50.483

That works very well, thank you! Especially for the psc suggestion. Now I just wish I knew how to pass tab as the single delimiter character to psc... – weronika – 2012-01-01T03:33:20.563

@weronika: If -d '\t' doesn't work, try -d $'\t' – Paused until further notice. – 2012-01-01T03:51:32.897

@Dennis: Yes, I figured that out eventually. :) Great solution, I use this all the time now. – weronika – 2012-01-28T06:16:49.250

12

This works to output a pretty print version of a tab delimited file

column -t -s $'\t' list-of-entries.txt

toobsco42

Posted 2010-05-11T20:16:24.170

Reputation: 221

Thanks, this worked fine for me, after piping the results into less -S as such:

column -t -s $'\t' someFile.tsv | less -S – bug313 – 2019-06-26T11:04:34.240

One caveat though ... If the file contains empty cells, those will be lost, since (from the man page:) "By default, the column command will merge multiple adjacent delimiters into a single delimiter when using the -t option; this option disables that behavior. This option is a Debian GNU/Linux extension." 'this option' being -n, hence the command should be: column -nts$'\t' someFile.tsv | less -S – bug313 – 2019-06-26T14:20:58.797

And lastly, since this -n switch is not available on macosx e.g., one possible work-around is to insert a space for empty cells, making use of perl's lookbehind: perl -pe 's/((?<=\t)|(?<=^))\t/ \t/g;' someFile.tsv | column -t -s$'\t' | less -S

Found this hint on: https://www.stefaanlippens.net/pretty-csv.html

– bug313 – 2019-07-04T15:03:02.320

8

Open the file in vim and set tab stop to something high, so the columns will be lined up. If you are not familiar with vim, first start it up:

vim some_file.csv

Then set tab stop to some high value, so the columns will be lined up. Type:

:set tabstop=20

Should lines become too long, you should also turn off wrapping, so you can scroll sideways instead of wrapping the text around:

:set nowrap

Moving around: there are several ways, but the most straightforward ones like arrow keys and pgup/pgdown/home/end will work. Some other useful movement commands:

CTRL+U: move half screen up
CTRL+D: move half screen down
gg: move to top
G: move to bottom

You can search for text the same way you would do in man:

/regular_expression (search forward)
?regular_expression (search backward)

Then type "n" to find the next match, and "N" to find the previous one.

You can also navigate using the mouse if your terminal supports it, and you type:

:set mouse=a

Edit: I forgot that you can exit with:

:q (if you haven't changed the text)
:wq (to save it before quitting)
:q! (to abandon changes)

petersohn

Posted 2010-05-11T20:16:24.170

Reputation: 2 554

That worked pretty well -- until I got to the column that was somewhere between 40 and 200 characters. Spacing after that was confused, as you might imagine. But tab-settings + nowrap came close! I will have to remember that. – Michael H. – 2010-05-11T20:38:44.803

Oh, awesome!! So simple. I can't believe I never thought of doing this when struggling with those tab-separated files in vi. – weronika – 2011-12-30T16:29:26.133

6

There is another solution, which involves a script. Save this script to, for example, tab.pl.

#!/usr/bin/perl

use strict;

my @lines;
# first read the file into a list of lists
while (<>)
{
    chomp; # remove the newline from the end of the line
    my @fields = split("\t");
    push @lines, \@fields;
}
my @lengths;
# calculate the maximum lengths of each field
foreach (@lines)
{
    for (my $i = 0; $i < scalar @$_; $i++)
    {
        $lengths[$i] = $lengths[$i] < length $$_[$i] ? length $$_[$i] : $lengths[$i];
    }
}
# now print the text aligned
foreach (@lines)
{
    for (my $i = 0; $i < scalar @$_; $i++)
    {
        print $$_[$i], " " x ($lengths[$i] - length ($$_[$i]) + 1);
    }
    print "\n";
}

Then just type:

perl tab.pl some_file.csv | less

Or save the result to a file and open it with your favourite text editor:

perl tab.pl some_file.csv > result.txt

petersohn

Posted 2010-05-11T20:16:24.170

Reputation: 2 554

Something like that is what I was thinking of when I said I could make a reformatter to replace tabs with spaces and pad. I will freely admit that your version is much more compact than mine would've been! Thank you! – Michael H. – 2010-05-12T18:49:41.123

Very nice, thank you! I grabbed it, it works pretty well, though I'll have to modify it a bit to deal with the fact that my files tend to contain non-tab-separated headers/footers that should be dealt with separately. – weronika – 2011-12-30T16:36:50.240

1

pr allows you to expand tabs to a given number of spaces with -e. Don't forget to pass -t -T so that it doesn't actually format the whole page for printing.

Ignacio Vazquez-Abrams

Posted 2010-05-11T20:16:24.170

Reputation: 100 516