cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / docs / nushell / pipelines.md
pipelines.md 8.7K rendered
1---2title: "Pipelines"3sidebar_position: 24---56# Pipelines78012 can be a stage in a pipeline: a table comes in, you look at it or9edit it in the terminal, and what you send back goes on to the next10command. With the [`sheet` command](#the-sheet-command) installed11(`012 nu --install-module`), that stage is one word:1213```nu14ls | select name size | sheet --send selection | where size > 1kb15```1617![In nushell, ls's table goes through sheet, three of its rows are selected, and quitting sends them on for nu to keep filtering by size](../media/pipeline.gif)1819`sheet` is shorthand for20`to nuon | ^012 --pipe | from nuon`:21[`to nuon`](https://www.nushell.sh/commands/docs/to_nuon.html) writes22the table in NUON, nushell's own notation, so file sizes, durations and23dates arrive as themselves, and24[`from nuon`](https://www.nushell.sh/commands/docs/from_nuon.html) reads25what 012 sends back with the same types ([Types](types.md)). Without the26module, write it out.2728The screen is the terminal's own (`/dev/tty`, or the console on29Windows), not standard input or output, so the pipeline's data never30mixes with what 012 draws, and nothing but the table reaches standard31output.3233```mermaid34sequenceDiagram35 participant nu as nushell36 participant o12 as 012 --pipe37 participant tty as the terminal38 nu->>o12: to nuon: the table on standard input39 o12->>tty: the sheet, drawn on /dev/tty40 tty->>o12: keys: edit, select, Ctrl+Q, Enter41 o12->>nu: the selection or the sheet, as NUON on standard output42 Note over nu: from nuon: a table with its types43```4445| Command | Reads | Writes |46|---|---|---|47| `012 -` | A table from standard input, into a new sheet | Nothing; the table stays in 012 until you save or download it |48| `012 --pipe` | A table from standard input, or a file named after it | The sheet or the selection, to standard output, when you quit (asking which, unless `--send` says) |49| `sheet`, `sheet view` | As `012 --pipe` and `012 -`, from nushell values | A nushell table, or nothing |5051## Reading a table: `012 -`5253`012 -` reads a table from standard input into a new sheet named54`stdin`, and tells its format from the text:5556| Text starts with | Read as |57|---|---|58| `[` or `{`, and is all JSON | JSON: a list of records, a record, or records one after another (NDJSON) |59| `[` or `{` otherwise | NUON: a table (`[[name, size]; [a, 1kb]]`), a list of records, a record |60| anything else | delimited text: TSV when tabs separate the fields, otherwise CSV, as [imports](../files/README.md#import-and-download) read them |6162The first row holds the column names; a record that brings a new key63adds a column. The sheet has no file and counts as unsaved, so quitting64asks first, as with any unsaved sheet. `max-cells` applies as it does to65imports: whole rows while they fit, and the context line says how many66were left out. While a long input is still coming in, the status line67counts its rows and Esc stops reading.6869## Sending it on: `012 --pipe`7071`012 --pipe` reads standard input as `012 -` does (or a file named on72the command line, `012 --pipe sales.csv`), and quitting sends a table to73standard output:7475- The status line says what Ctrl+Q sends and in which format76 (`Ctrl+Q send the sheet as NUON`, or `send B2:D9 as NUON` while a77 range is selected).78- Quit (Ctrl+Q, File > Quit, `:q`) asks: Enter sends the selection when79 one is made, or else the sheet; S sends the whole sheet instead; D80 quits without sending; Esc goes back to the sheet.81- File > Quit and send selection and File > Quit and send sheet send82 without asking, and File > Quit without sending (or `:q!`) sends83 nothing. They're in the menus and the palette only with `--pipe`.8485`--send` makes Quit send without asking, for a pipeline that always86wants the same thing back:8788| `--send` | Quit sends |89|---|---|90| `ask` (the default) | What you choose at the question above |91| `selection` | The selection; with only the active cell selected, the sheet, as Enter at the question does |92| `sheet` | The sheet, whatever is selected |9394```nu95open orders.csv | to nuon | ^012 --pipe --send sheet | from nuon | save -f orders.nuon96```9798What quitting sends, and the [exit status](#the-exit-status) the99pipeline sees:100101```mermaid102flowchart TD103 quit["Quit: Ctrl+Q, File > Quit, :q"] --> send{"--send"}104 send -->|ask| question["the question"]105 send -->|selection| sel["the selection, or the sheet while only the active cell is selected"]106 send -->|sheet| sheet["the sheet"]107 question -->|Enter| sel108 question -->|S| sheet109 question -->|D| none["nothing, exit status 1"]110 question -->|Esc| back["back to the sheet"]111 sel --> out["the table on standard output, exit status 0"]112 sheet --> out113```114115The status line still names what Ctrl+Q will send, and File > Quit116without sending stays in the menu. The active cell on its own isn't a117selection to send, as at the question: `--send selection` sends the118sheet until a range is selected.119120The sheet is its used range from A1. A selection is sent as selected,121and its first row names the columns. Either way, rows a filter hides122stay behind, as Sheets copies a filtered range.123124The table goes out in the format it came in (NUON, JSON, CSV or TSV);125from a file of another kind, such as `.xlsx` or `.012`, as NUON.126`--to nuon`, `--to json`, `--to csv` or `--to tsv` picks the format127instead:128129```nu130open budget.xlsx | to nuon | ^012 --pipe --to csv | save budget.csv131```132133## The `sheet` command134135The nushell module that comes with 012 ([Install the `sheet`136command](README.md#install-the-sheet-command)) wraps both commands, so a137pipeline needs neither `^012` nor NUON on either side:138139```nu140ls | select name size | sheet | where size > 1kb141ps | sheet view142sheet budget.xlsx | save -f budget.csv143```144145![In nushell, ls's table goes through sheet, three rows are selected and sent back, and nu keeps filtering them by size; then quitting without sending raises sheet's error](../media/sheet.gif)146147`sheet` is `to nuon | ^012 --pipe --to nuon | from nuon`: it opens the148table piped in, or the file it names, and returns what you send back149with its types. `sheet --send sheet` and `sheet --send selection` pass150`--send` on, so quitting sends without asking:151152```nu153ls | sheet --send sheet | where size > 1kb154```155 Text piped in, such as `open --raw data.csv`, goes to156012 as it is, to be read as `012 -` reads it. `sheet view` is157`to nuon | ^012 -`, and returns nothing. Quitting without sending makes158`sheet` fail with 012's reason:159160```nu161try { ls | sheet | save -f picked.nuon } catch {|e| print $e.msg }162# quit without sending anything to the pipeline163```164165## The exit status166167Quitting without sending (D at the question, File > Quit without168sending, `:q!`) writes nothing and exits169with status 1, so the pipeline stops rather than carrying on with170nothing. Nushell treats that171as a failed external command and stops the pipeline with an error172([Failing external commands](https://www.nushell.sh/book/pipelines.html#failing-external-commands-in-a-pipeline));173[`try`](https://www.nushell.sh/commands/docs/try.html) catches it:174175```nu176try { ls | to nuon | ^012 --pipe | from nuon | save -f picked.nuon } catch { print "nothing sent" }177```178179## Recipes180181Each of these reads a table into 012 with `sheet view`; `sheet`182instead carries on with what you send back. Without the module, each183`sheet view` is `to nuon | ^012 -`.184185```nu186# Files, largest first: sizes in the Size format, dates as dates187ls | sort-by size --reverse | sheet view188189# Processes: CPU as numbers, memory as file sizes190ps | select pid name cpu mem | sheet view191192# Every CSV here, one table, with the file each row came from193glob *.csv | each {|f| open $f | insert file ($f | path basename) } | flatten | sheet view194195# An API's JSON, its dates made datetimes on the way196http get https://api.github.com/repos/nushell/nushell/releases | select name published_at | update published_at { into datetime } | sheet view197198# This computer: sys host is a record, which comes in as one row199sys host | sheet view200sys disks | select mount total free | sheet | sort-by free201```202203The commands are nushell's:204[`ls`](https://www.nushell.sh/commands/docs/ls.html),205[`ps`](https://www.nushell.sh/commands/docs/ps.html),206[`open`](https://www.nushell.sh/commands/docs/open.html),207[`http get`](https://www.nushell.sh/commands/docs/http_get.html),208[`sys host`](https://www.nushell.sh/commands/docs/sys_host.html).209The [Cookbook](cookbook.md) has longer examples.210211## Other shells212213Any command that writes CSV, TSV or JSON can feed 012, and the exit214status works as usual:215216```sh217ps -eo pid,comm,%cpu | awk '{$1=$1}1' OFS='\t' | 012 --pipe | sort -t$'\t' -k3 -rn218curl -s https://api.example.com/items | 012 --pipe --to csv > items.csv219sqlite3 -csv -header app.db 'select * from users' | 012 --pipe > users.csv || echo "not sent"220```221222`.nuon` and `.json` files also open, import and download like any other223[file](../files/README.md).