397

Anyone know of a command-line CSV viewer for Linux/OS X? I'm thinking of something like less but that spaces out the columns in a more readable way. (I'd be fine with opening it with OpenOffice Calc or Excel, but that's way too overpowered for just looking at the data like I need to.) Having horizontal and vertical scrolling would be great.

Benjamin Oakes
  • 12,262
  • 12
  • 65
  • 83

18 Answers18

554

You can also use this:

column -s, -t < somefile.csv | less -#2 -N -S

column is a standard unix program that is very convenient -- it finds the appropriate width of each column, and displays the text as a nicely formatted table.

Note: whenever you have empty fields, you need to put some kind of placeholder in it, otherwise the column gets merged with following columns. The following example demonstrates how to use sed to insert a placeholder:

$ cat data.csv
1,2,3,4,5
1,,,,5
$ sed 's/,,/, ,/g;s/,,/, ,/g' data.csv | column -s, -t
1  2  3  4  5
1           5
$ cat data.csv
1,2,3,4,5
1,,,,5
$ column -s, -t < data.csv
1  2  3  4  5
1  5
$ sed 's/,,/, ,/g;s/,,/, ,/g' data.csv | column -s, -t
1  2  3  4  5
1           5

Note that the substitution of ,, for , , is done twice. If you do it only once, 1,,,4 will become 1, ,,4 since the second comma is matched already.

Lekensteyn
  • 64,486
  • 22
  • 159
  • 192
user437522
  • 5,624
  • 1
  • 16
  • 2
  • 2
    I really like this option -- it's good to know about `column`. I ended up making this a short shell script (most of it is boilerplate "how do I use it?" and error checking code). https://github.com/benjaminoakes/utilities/blob/master/view-csv – Benjamin Oakes Nov 16 '10 at 13:24
  • 29
    The 'Debian GNU/Linux' version of column has the '-n' option: "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." – klokop Nov 18 '13 at 10:25
  • 8
    It seems to break if you have column values (quoted) with commas in them. Any idea how to fix this? – TM. Jun 17 '14 at 11:12
  • 1
    maybe try converting it to tabseparated values like this: `cat /tmp/foo.csv | gawk -vFS='^"|","|"$|",|,"|,' '{out=""; for(i=1;i – coderofsalvation Apr 13 '15 at 13:13
  • 3
    from `man column`: `-n 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.` – ezdazuzena Jun 17 '16 at 07:59
  • 1
    Where can one get a copy of the 'Debian GNU/Linux' version of column (for Mac)? – Oliver Joseph Ash Sep 12 '16 at 14:36
  • 1
    To do the right thing for empty first/last fields, you actually need two more `sed` substitutions: `s/^,/, /` and `s/,$/, /`. The final command is then: `sed 's/,,/, ,/g;s/,,/, ,/g;s/^,/, /;s/,$/, /' data.csv | column -s, -t` – yuzeh Oct 07 '16 at 19:47
  • 19
    Unfortunately if a value contains a comma, it will be split even if it is quoted. – ffarquet Feb 22 '17 at 15:49
  • My data is separated by semicolons instead of commas, and so this doesn't seem to work correctly. Is there any way to quickly change what the separator is? – Pro Q Jun 19 '18 at 19:10
  • What does this hash supposed to do? Is is some bash-specific magic? `zsh: no matches found: -#2` – varepsilon Aug 02 '18 at 13:24
  • 2
    @ProQ You should use `column -s; -t` instead of `column -s, -t`. – Akshay Gaur Aug 08 '18 at 18:17
  • 1
    I actually prefer `cat data.csv | column -t, -s | less` having just wiped an example .csv file putting the < the wrong way round. – Phlebass Jan 14 '19 at 12:14
  • Pretty critical issue if whitespace matters for a csv reader. For instance if you don't have a value for any line if you have a space (or not) before a line that starts with a comma, you have completely different output. I'd really like to vote for this but that is a deal breaker. – jasonleonhard Oct 26 '19 at 21:26
  • Perhaps this is a solution: 1. remove all white space 2. add a space in front of every comma that doesn't have a value in front of it aka a line that start with a comma & when a comma follows another comma. Then you might have reliable output. – jasonleonhard Oct 26 '19 at 21:28
  • Can this be done somehow with `tail -f`? – Jeppe Feb 27 '20 at 18:34
  • 1
    To add a horizontal line after every csv line in file `column -tns, cities.csv | nl | awk '1; {gsub(".","─")}1' | less -#10 -S` – webh Aug 05 '20 at 14:19
  • From version 2.23 the `-s` option is non-greedy and will not merge empty columns. – Pan P Nov 19 '20 at 14:50
  • 1
    pspg (postgresql pager) is fullfeatred csv viewer... Current version is just working `pspg --csv -af file.csv`. For screenshot see https://github.com/okbob/pspg/ – Lubo Jan 05 '21 at 12:49
  • use `alias csv='function _csv(){column -s, -t < $1v | less -#2 -N -S};_csv'` in bash – Jithin Johnson Aug 21 '21 at 16:08
145

You can install csvtool (on Ubuntu) via

sudo apt-get install csvtool

and then run:

csvtool readable filename | view -

This will make it nice and pretty inside of a read-only vim instance, even if you have some cells with very long values.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
d_chall
  • 1,451
  • 1
  • 9
  • 2
  • 4
    For those not on Debian-base distros, this tool seems to originate from here: http://docs.camlcity.org/docs/godisrc/ocaml-csv-1.1.6.tar.gz Unfortunately the "homepage" link is dead, and I don't see an easy way to download the whole archive in a go. – cincodenada Jan 03 '14 at 00:39
  • 13
    The tool can't handle files with 100Mb+ – PedroSena Aug 08 '14 at 11:19
  • 8
    This tool is available from the `ocaml-csv` package in the `base` for me in Centos7 – Bryce Guinta Jul 29 '16 at 21:16
91

Have a look at csvkit. It provides a set of tools that adhere to the UNIX philosophy (meaning they are small, simple, single-purposed and can be combined).

Here is an example that extracts the ten most populated cities in Germany from the free Maxmind World Cities database and displays the result in a console-readable format:

$ csvgrep -e iso-8859-1 -c 1 -m "de" worldcitiespop | csvgrep -c 5 -r "\d+" 
  | csvsort -r -c 5 -l | csvcut -c 1,2,4,6 | head -n 11 | csvlook
-----------------------------------------------------
|  line_number | Country | AccentCity | Population  |
-----------------------------------------------------
|  1           | de      | Berlin     | 3398362     |
|  2           | de      | Hamburg    | 1733846     |
|  3           | de      | Munich     | 1246133     |
|  4           | de      | Cologne    | 968823      |
|  5           | de      | Frankfurt  | 648034      |
|  6           | de      | Dortmund   | 594255      |
|  7           | de      | Stuttgart  | 591688      |
|  8           | de      | Düsseldorf | 577139      |
|  9           | de      | Essen      | 576914      |
|  10          | de      | Bremen     | 546429      |
-----------------------------------------------------

Csvkit is platform independent because it is written in Python.

Sandeep
  • 28,307
  • 3
  • 32
  • 24
Kai Sternad
  • 22,214
  • 7
  • 47
  • 42
55

Tabview: lightweight python curses command line CSV file viewer (and also other tabular Python data, like a list of lists) is here on Github

Features:

  • Python 2.7+, 3.x
  • Unicode support
  • Spreadsheet-like view for easily visualizing tabular data
  • Vim-like navigation (h,j,k,l, g(top), G(bottom), 12G goto line 12, m - mark, ' - goto mark, etc.)
  • Toggle persistent header row
  • Dynamically resize column widths and gap
  • Sort ascending or descending by any column. 'Natural' order sort for numeric values.
  • Full-text search, n and p to cycle between search results
  • 'Enter' to view the full cell contents
  • Yank cell contents to clipboard
  • F1 or ? for keybindings
  • Can also use from python command line to visualize any tabular data (e.g. list-of-lists)
Scott Hansen
  • 762
  • 6
  • 8
37

If you're a vimmer, use the CSV plugin, which is juuust beautiful:

beautiful.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
Myer
  • 3,670
  • 2
  • 39
  • 51
28

The nodejs package tecfu/tty-table can be globally installed to do precisely this:

apt-get install nodejs
npm i -g tty-table
cat data.csv | tty-table

tecfu/tty-table

It can also handle streams.

For more info, see the docs for terminal usage here.

user3751385
  • 3,752
  • 2
  • 24
  • 24
  • 2
    Please leave a reason if you downvote. This package works and works well. – user3751385 Jul 12 '16 at 16:49
  • 36
    node is a general purpose scripting system with CLI bindings, how is that different from using a perl one-liner or something from CPAN? – Racheet Aug 02 '16 at 18:14
  • I really like this option, but when I pipe it to less, it doesn't look right. Do you know if something extra is required to make it work with less? – plafratt Apr 19 '20 at 01:13
  • This package breaks if the file contains many columns (in particular more than the horizontal width of the terminal screen can handle) and doesn't align them properly thereafter. – gented Jun 04 '20 at 17:49
24

xsv is more than a viewer. I recommend it for most CSV task on the command line, especially when dealing with large datasets.

smartmic
  • 661
  • 5
  • 15
11

I used pisswillis's answer for a long time.

csview()
{
    local file="$1"
    sed "s/,/\t/g" "$file" | less -S
}

But then combined some code I found at http://chrisjean.com/2011/06/17/view-csv-data-from-the-command-line which works better for me:

csview()
{
    local file="$1"
    cat "$file" | sed -e 's/,,/, ,/g' | column -s, -t | less -#5 -N -S
}

The reason it works better for me is that it handles wide columns better.

Tom Weiss
  • 797
  • 1
  • 8
  • 15
9

Ofri's answer gives you everything you asked for. But.. if you don't want to remember the command you can add this to your ~/.bashrc (or equivalent):

csview()
{
local file="$1"
sed "s/,/\t/g" "$file" | less -S
}

This is exactly the same as Ofri's answer except I have wrapped it in a shell function and am using the less -S option to stop the wrapping of lines (makes less behaves more like a office/oocalc).

Open a new shell (or type source ~/.bashrc in your current shell) and run the command using:

csview <filename>

pisswillis
  • 1,569
  • 2
  • 14
  • 19
6

Here's a (probably too) simple option:

sed "s/,/\t/g" filename.csv | less
Ofri Raviv
  • 24,375
  • 3
  • 55
  • 55
  • 3
    That was my first inclination as well. But you have to insert enough tabs to match the longest value for your column... Started getting a little complicated and I thought "someone else must have done this already." – Benjamin Oakes Dec 09 '09 at 20:54
  • 4
    You're also ignoring the fact that commas might be quoted and therefore not separators. (amongst other things) – Ariel Allon Aug 21 '18 at 21:33
6

Yet another multi-functional CSV (and not only) manipulation tool: Miller. From its own description, it is like awk, sed, cut, join, and sort for name-indexed data such as CSV, TSV, and tabular JSON. (link to github repository: https://github.com/johnkerl/miller)

Nikos Alexandris
  • 708
  • 2
  • 22
  • 36
  • 1
    I landed here through a search engine so if somebody finds this answer, here's a handy miller command line that pretty-prints CSV headers, draws table borders and right-aligns the column values: `mlr --icsv --opprint --barred --right cat YOUR_FILE.csv` (replace `--icsv` with `--itsv` if your file is TSV). – dimitarvp Jun 16 '22 at 22:28
5

tblless in the Tabulator package wraps the unix column command, and also aligns numeric columns.

stefan.schroedl
  • 866
  • 9
  • 19
  • It's not bad, it works reliably but formatting can definitely be better, and it doesn't infer maximum column widths well -- it kind of blindly enforces an arbitrary limit. Miller (`mlr`) definitely does it better. – dimitarvp Jun 16 '22 at 22:37
3

I've created tablign for these (and other) purposes. Install with

pip install tablign

and

$ cat test.csv
Header1,Header2,Header3
Pizza,Artichoke dip,Bob's Special of the Day
BLT,Ham on rye with the works,
$ tablign test.csv
Header1 , Header2                   , Header3
Pizza   , Artichoke dip             , Bob's Special of the Day
BLT     , Ham on rye with the works ,

Also works if the data is separated by something else than commas. Most importantly, it preserves the delimiters so you can also use it to style your ASCII tables without sacrificing your [Markdown,CSV,LaTeX] syntax.

Nico Schlömer
  • 53,797
  • 27
  • 201
  • 249
2

Using TxtSushi you can do:

csvtopretty filename.csv | less -S
Derek Mahar
  • 27,608
  • 43
  • 124
  • 174
Keith
  • 2,820
  • 5
  • 28
  • 39
  • Downvote for not being a one line install procedure. I don't have the time to compile this :(. If you could provide a package that would be awesome. – masterxilo Nov 30 '18 at 19:01
  • 1
    @masterxilo that's not a valid reason to downvote. Many packages today require several steps to install. Plus, it would probably be faster to install than to write the comment. – Yuval Meshorer Nov 24 '19 at 12:39
2

I wrote this csv_view.sh to format CSVs from the command line, this reads the entire file to figure out the optimal width of each column (requires perl, assumes there are no commas in fields, also uses less):


#!/bin/bash

perl -we '
  sub max( @ ) {
    my $max = shift;

    map { $max = $_ if $_ > $max } @_;
    return $max;
  }

  sub transpose( @ ) {
    my @matrix = @_;
    my $width  = scalar @{ $matrix[ 0 ] };
    my $height = scalar @matrix;

    return map { my $x = $_; [ map { $matrix[ $_ ][ $x ] } 0 .. $height - 1 ] } 0 .. $width - 1;
  }

  # Read all lines, as arrays of fields
  my @lines = map { s/\r?\n$//; [ split /,/ ] } ;

  my $widths =
    # Build a pack expression based on column lengths
    join "",

    # For each column get the longest length plus 1
    map { 'A' . ( 1 + max map { length } @$_ ) }

    # Get arrays of columns
    transpose

    @lines
  ;

  # Format all lines with pack
  map { print pack( $widths, @$_ ) . "\n" } @lines;
' $1 | less -NS

Jean Vincent
  • 11,995
  • 7
  • 32
  • 24
2

Tabview is really good. Worked with 200+MB files that displayed nicely which were buggy with LibreOffice as well as csv plugin in gvim.

The Anaconda version is available here: https://anaconda.org/bioconda/tabview

pratyahara
  • 154
  • 1
  • 5
0

I wrote a script, viewtab , in Groovy for just this purpose. You invoke it like:

viewtab filename.csv

It is basically a super-lightweight spreadsheet that can be invoked from the command line, handles CSV and tab separated files, can read VERY large files that Excel and Numbers choke on, and is very fast. It's not command-line in the sense of being text-only, but it is platform independent and will probably fit the bill for many people looking for a solution to the problem of quickly inspecting many or large CSV files while working in a command line environment.

The script and how to install it are described here:

http://bayesianconspiracy.blogspot.com/2012/06/quick-csvtab-file-viewer.html

0

There's this short command line script in python: https://github.com/rgrp/csv2ascii/blob/master/csv2ascii.py

Just download and place in your path. Usage is like

csv2ascii.py [options] csv-file-path

Convert csv file at csv-file-path to ascii form returning the result on stdout. If csv-file-path = '-' then read from stdin.

Options:

  -h, --help            show this help message and exit
  -w WIDTH, --width=WIDTH
                        Width of ascii output
  -c COLUMNS, --columns=COLUMNS
                        Only display this number of columns
Rufus Pollock
  • 2,295
  • 21
  • 20