A timesaver: look at, count and reshape a data file in seconds, without a spreadsheet program or a script, with the keys run for real on 400 sample rows.
▶Prefer to watch? This short video explains what VisiData is for, then runs this page's main keys on a real Ubuntu 24.04 machine, with on-screen captions and no voiceover. Click to play, or watch it on YouTube.
vd: a spreadsheet for your terminal. Open a data file, look around, sort, count, pick rows, pivot, save.
vd orders.csv open a file as a sheet
Shift+F frequency table of the column under the cursor
Shift+W pivot table
q back one sheet gq quit everything
VisiData (the command is vd) is a viewer and editor for tabular data that runs in the terminal. Everything you open or create is a sheet: a CSV file, a frequency table of one column, a pivot table. You move around with the keyboard, and q takes you back one sheet, so looking at a file from different angles costs nothing. It is the quickest way to answer "what is in this export?" on a server, over SSH, with no spreadsheet program and no throwaway script.
This page is the written version of the Timesavers video. Every key below was run for real, in an Ubuntu 24.04 container with VisiData 3.0.2 from the Ubuntu package, on a sample file of 400 made-up orders (columns order_id, date, region, product, qty, price and status). The screens shown are the real screens from that run, shortened to the first rows. Only CSV and JSON files were opened; the section "What was not run" lists the rest.
What VisiData is good for
Use it when you have a table and a question, and want the answer in less time than it takes to open another program or write a script:
what is in this file? open it and look. The column names stay on top while you scroll.
which values are there, how many? a frequency table of any column (Shift+F).
show me only the returned orders select rows by a pattern and open just those.
totals by two columns a pivot table (Shift+W).
turn this CSV into JSON batch mode converts without opening the screen.
It reads CSV, TSV, JSON and many more formats with the same keys. How it copes with very large files was not tested here. It does not replace a database or a real spreadsheet for formulas and charts. It is for looking, counting, picking and reshaping.
Install and open a file
VisiData is in the Ubuntu package archive:
$ sudo apt install visidata
$ apt-cache policy visidata | head -3
visidata:
Installed: 3.0.2-1
Candidate: 3.0.2-1
$ vd --version
saul.pw/VisiData v3.0.2
(The two lines above are the real output; the version in the Ubuntu 24.04 archive is 3.0.2.) Open a file by giving its name, and VisiData chooses the format from the extension:
$ vd orders.csv
order_id β date β region β product β qty β price β status β
1022 β 2026-01-05 β East β Headset β 1 β 110 β pending β
1267 β 2026-01-05 β East β Webcam β 2 β 85 β shipped β
1188 β 2026-01-06 β West β Dock β 1 β 180 β shipped β
1009 β 2026-01-07 β North β Keyboard β 2 β 70 β shipped β
1390 β 2026-01-07 β South β Dock β 1 β 180 β shipped β
1133 β 2026-01-10 β North β Dock β 2 β 180 β shipped β
1097 β 2026-01-11 β East β Monitor β 1 β 240 β shipped β
1βΊ orders| k go-up 400 rows
What is on the screen. The top line is a menu bar (File, Edit, View and so on; Alt+H opens the help menu). Below it is the header row with the column names, then one row per record. The bottom line is the status bar: on the left a number and the sheet name (1 > orders is the first sheet), on the right the last key you pressed and the command it ran (here k, go-up) and the number of rows (400). The line of β marks at the right edge is the end of the table.
Two things you may see on a fresh install and not in the pictures here. A box with recent status messages can sit over the table until the next key, and a help sidebar opens beside some sheets. The sidebar is switched off for these pictures with one line in ~/.visidatarc:
options.disp_sidebar = False
and VisiData's own help lists the b key as the sidebar toggle (not run).
Move around
h, j, k and l move the cursor left, down, up and right, the same keys as in vim (the lab used these). In the picture above the k at the right of the status bar is the last key pressed. The column the cursor is in is the one every column command works on, so most of what follows begins with "move to the column".
q quit the current sheet and go back to the one before it (quit VisiData when it is the last)
gq quit every sheet at once
Alt+H open the help menu (shown on the top line)
The g in front of a key often means "all": gq is quit all sheets. Moving with the arrow keys, Page Up and Page Down was not run in the lab.
Sort a column
Move the cursor to the price column (five columns to the right of the first one, so lllll). Columns read from a CSV file start out as text, and VisiData shows a type mark after the column name. # sets the column type to a whole number, and the header then reads price#. Then ] sorts the sheet by that column, biggest first:
keys: cursor on price, then # and ]
order_id β date β region β product β qty ββprice#β status β
1054 β 2026-01-16 β South β Laptop β 2 β 950 β shipped β
1335 β 2026-01-17 β West β Laptop β 5 β 950 β pending β
1006 β 2026-01-23 β South β Laptop β 1 β 950 β shipped β
1136 β 2026-01-28 β West β Laptop β 2 β 950 β shipped β
1033 β 2026-01-29 β North β Laptop β 2 β 950 β shipped β
1βΊ orders| ] sort-desc 400 rows
The arrow in the header (β price#) shows the sort column and the direction, and the status bar names the command that ran (sort-desc). [ sorts the other way:
keys: [
order_id β date β region β product β qty ββprice#β status β
1009 β 2026-01-07 β North β Keyboard β 2 β 70 β shipped β
1274 β 2026-01-13 β South β Keyboard β 2 β 70 β returned β
1296 β 2026-01-14 β West β Keyboard β 1 β 70 β shipped β
1157 β 2026-01-18 β North β Keyboard β 2 β 70 β shipped β
1253 β 2026-01-24 β South β Keyboard β 1 β 70 β shipped β
1βΊ orders| [ sort-asc 400 rows
The file on disk is not changed. A sort only changes the sheet you are looking at, until you save it (a later section).
Count values: the frequency table
Move the cursor to the region column (hhh from price) and press Shift+F (a capital F). VisiData opens a new sheet that counts every distinct value of that column, with the percentage and a bar:
keys: Shift+F on the region column
region ββcountβ―β percent%β histogram ~β
North β 111 β 27.75 β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
East β 106 β 26.50 β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
South β 92 β 23.00 β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
West β 91 β 22.75 β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
2βΊ orders_region_freq| Shift+F 4 bins
This is the answer to "what values does this column have, and how many of each?", for any column. The status bar shows sheet 2, named orders_region_freq, with 4 bins. Press Enter on a row of the frequency table and VisiData opens a copy of the original sheet with only the rows in that bin. Here Enter on the first row (North):
keys: Enter
order_id β date β region β product β qty ββprice#β status β
1033 β 2026-01-29 β North β Laptop β 2 β 950 β shipped β
1156 β 2026-02-05 β North β Laptop β 3 β 950 β shipped β
1389 β 2026-02-06 β North β Laptop β 1 β 950 β shipped β
1050 β 2026-02-10 β North β Laptop β 2 β 950 β shipped β
1215 β 2026-03-17 β North β Laptop β 3 β 950 β returned β
3βΊ orders_North| Enter 111 rows
Sheet 3 is orders_North with 111 rows, and it is still sorted by price, because it is a copy of the sorted sheet. Press q twice to go back through the sheets to the original (the lab did this, and sheet 1 came back unchanged).
Select rows and open only those
A selection marks rows, and then a command works on the marked rows. Move to the status column (llll from region) and press | (the pipe). VisiData asks for a pattern (a regular expression) to match in the current column. Type returned and press Enter: every row whose status matches is selected. The double quote key (") opens a new sheet with only the selected rows:
keys: | returned Enter and then "
order_id β date β region β product β qty ββprice#β status β
1215 β 2026-03-17 β North β Laptop β 3 β 950 β returned β
1183 β 2026-03-19 β North β Laptop β 3 β 950 β returned β
1070 β 2026-07-12 β North β Laptop β 3 β 950 β returned β
1019 β 2026-09-11 β South β Laptop β 2 β 950 β returned β
1031 β 2026-04-12 β South β Monitor β 3 β 240 β returned β
1374 β 2026-06-03 β South β Monitor β 2 β 240 β returned β
4βΊ orders_selectedref| " 33 rows
Thirty-three rows were returned, across several regions and products, and they are now a sheet of their own (sheet 4, orders_selectedref). The original sheet is still there under it (q goes back). Selecting by a pattern in one column and then opening the selection is the quickest way to cut a big file down to the rows you care about.
A pivot table in a few keys
A pivot table counts (or sums) rows by two columns at once. Go back to the original sheet (q), move to the region column and press ! to make it a key column. A key column is pinned at the left, and it becomes the rows of the pivot. Move one column to the right, to product, and press Shift+W (a capital W):
keys: ! l Shift+W
region β Laptop#β Monitor#β Dock#β Headset#β Webcam#β Keyboard#β
South β 15 β 19 β 21 β 12 β 14 β 11 β
West β 14 β 7 β 14 β 24 β 15 β 17 β
North β 19 β 23 β 15 β 20 β 20 β 14 β
East β 17 β 11 β 13 β 25 β 21 β 19 β
5βΊ orders_pivot_product_count| Shift+W 4 grouped rows
Each row is a region, each column a product, and each cell is how many orders there are for that pair. The status bar shows sheet 5, orders_pivot_product_count, with 4 grouped rows. Press q to leave the pivot table. This is the table people usually open a spreadsheet program to make.
Save the result
Ctrl+S saves the current sheet. It asks for a file name and the name it offers is the name of the file you opened, so pressing Enter straight away would overwrite your original. Clear the name first. In the lab, Ctrl+A moved to the start of the line and Ctrl+K deleted the rest, then the new name was typed:
keys: Ctrl+S
save to: orders.csv Ctrl+S save-sheet 400 rows
keys: Ctrl+A, Ctrl+K, then typing top.csv
save to: top.csv Ctrl+S save-sheet 400 rows
After Enter the status bar printed saving 1 sheets to top.csv as csv. The file on disk has the rows in the order of the sheet, which was sorted ascending by price at that moment:
$ head -3 top.csv
order_id,date,region,product,qty,price,status
1009,2026-01-07,North,Keyboard,2,70,shipped
1274,2026-01-13,South,Keyboard,2,70,returned
The CSV format was chosen from the .csv extension. Other formats were not run in the lab. The sort you made is in the saved file, so save what you are looking at on purpose.
Convert a file without the screen
Batch mode runs VisiData with no interface at all: -b (batch) and -o to name the output file. The file type of the output comes from its extension. CSV to JSON:
$ vd orders.csv -b -o orders-copy.json
$ head -3 orders-copy.json | cut -c1-96
saul.pw/VisiData v3.0.2
opening orders.csv as csv
saving 1 sheets to orders-copy.json as json
[
{"order_id": "1022", "date": "2026-01-05", "region": "East", "product": "Headset", "qty": "1", "
{"order_id": "1267", "date": "2026-01-05", "region": "East", "product": "Webcam", "qty": "2", "p
(VisiData prints a random short message after some commands, such as "Oh dear!" or "Explain yourself!". It is left out of the lines above.) Every value came out as text in quotation marks, because that is how it was read from the CSV file.
One thing to check after a conversion. The other direction, JSON to CSV, changed the numbers in the lab:
$ vd orders.json -b -o orders-from-json.csv
$ head -3 orders-from-json.csv
saul.pw/VisiData v3.0.2
opening orders.json as json
saving 1 sheets to orders-from-json.csv as csv
order_id,date,region,product,qty,price,status
1022.00,2026-01-05,East,Headset,1.00,110.00,pending
1267.00,2026-01-05,East,Webcam,2.00,85.00,shipped
The JSON file held whole numbers, and VisiData wrote them as 1022.00 and 110.00. Look at the numeric columns of the output before you use it, and fix the column types (# for whole numbers) in the interface first if they matter.
Keys used on this page
vd FILE open a file (the format comes from the extension)
vd FILE -b -o OUT convert without the screen (batch mode)
h j k l move left, down, up, right
# set the column type to a whole number
[ ] sort by this column, ascending, descending
Shift+F frequency table of this column; Enter opens one group
| then a pattern select the rows that match
" open only the selected rows as a new sheet
! make this column a key column
Shift+W pivot table (rows from the key columns, columns from this one)
Ctrl+S save the sheet (clear the offered name first: Ctrl+A, Ctrl+K)
q back one sheet
gq quit everything
Alt+H help menu
b show or hide the sidebar
What was not run in the lab
Only CSV and JSON files were opened and written. Excel files, SQLite, TSV and the other formats VisiData can read were not run. Loading a very large file (and how much memory it takes) was not tried, since the sample was 400 rows. Editing cells, adding columns with expressions, joining sheets, plots, the command log and replay (-p), and plug-ins were not run. Moving with the arrow keys and Page Up and Page Down was not run (h j k l was). The mouse was not used. Everything ran on Ubuntu 24.04 with VisiData 3.0.2 from the Ubuntu package; other versions may name or bind a key differently, and the help menu (Alt+H) shows what the version you have really does.
Common problems and tips
A column sorts or sums in a strange order. Columns from a CSV start as text. Set the type with # (whole number) before you sort or pivot on it, and look for the mark after the column name.
I pressed a key and something odd happened. Press q to go back, and look at the status bar: it names the command that the last key ran, which tells you what happened.
Ctrl+S overwrote my file. The offered name is the file you opened. Clear it first (Ctrl+A, Ctrl+K) and type a new one, as shown above, or save into another directory.
A box covers the table, or a sidebar takes half the screen. The box is the recent status messages and goes away at the next key. Put options.disp_sidebar = False in ~/.visidatarc to keep the sidebar off, or press b.
A converted file has numbers like 1022.00. See the end of the batch mode section: check the output of a JSON to CSV conversion.
Tips. Use the frequency table first on any new file: it shows in seconds which values a column really holds, including the typos. Keep the original file and save results under new names. When a step goes wrong, q and try again, since every view is its own sheet.