Working with tables

    To start off, let’s get a table that we can use:

    We can sort a table by calling the sort-by command and telling it which columns we want to use in the sort. Let’s say we wanted to sort our table by the size of the file:

    1. ───┬───────────────┬──────┬─────────┬────────────
    2. # │ name │ type │ size │ modified
    3. ───┼───────────────┼──────┼─────────┼────────────
    4. 0 lib.rs File 330 B 5 days ago
    5. 1 signature.rs File 1.2 KB 5 days ago
    6. 2 path.rs File 2.1 KB 5 days ago
    7. 3 files.rs File 4.6 KB 5 days ago
    8. 4 shapes.rs File 4.7 KB 5 days ago
    9. 5 lite_parse.rs File 6.3 KB 5 days ago
    10. 6 parse.rs File 49.8 KB 1 day ago
    11. ───┴───────────────┴──────┴─────────┴────────────

    We can sort a table by any column that can be compared. For example, we could also have sorted the above using the “name”, “accessed”, or “modified” columns.

    We can select data from a table by choosing to select specific columns or specific rows. Let’s a few columns from our table to use:

    1. > ls | select name size
    2. ───┬───────────────┬─────────
    3. # │ name │ size
    4. ───┼───────────────┼─────────
    5. 0 files.rs 4.6 KB
    6. 1 lib.rs 330 B
    7. 2 lite_parse.rs 6.3 KB
    8. 3 parse.rs 49.8 KB
    9. 4 path.rs 2.1 KB
    10. 5 shapes.rs 4.7 KB
    11. 6 signature.rs 1.2 KB
    12. ───┴───────────────┴─────────

    This helps to create a table that’s more focused on what we need. Next, let’s say we want to only look at the 5 smallest files in this directory:

    1. > ls | sort-by size | first 5
    2. ───┬──────────────┬──────┬────────┬────────────
    3. # │ name │ type │ size │ modified
    4. ───┼──────────────┼──────┼────────┼────────────
    5. 0 lib.rs File 330 B 5 days ago
    6. 1 signature.rs File 1.2 KB 5 days ago
    7. 2 path.rs File 2.1 KB 5 days ago
    8. 3 files.rs File 4.6 KB 5 days ago
    9. 4 shapes.rs File 4.7 KB 5 days ago
    10. ───┴──────────────┴──────┴────────┴────────────

    You’ll notice we first sort the table by size to get to the smallest file, and then we use the first 5 to return the first 5 rows of the table.

    You can also skip rows that you don’t want. Let’s skip the first two of the 5 rows we returned above:

    1. > ls | sort-by size | first 5 | skip 2
    2. ───┬───────────┬──────┬────────┬────────────
    3. # │ name │ type │ size │ modified
    4. ───┼───────────┼──────┼────────┼────────────
    5. 0 path.rs File 2.1 KB 5 days ago
    6. 1 files.rs File 4.6 KB 5 days ago
    7. 2 shapes.rs File 4.7 KB 5 days ago

    We’ve narrowed it to three rows we care about.

    Let’s look at a few other commands for selecting data. You may have wondered why the rows of the table are numbers. This acts as a handy way to get to a single row. Let’s sort our table by the file name and then pick one of the rows with the select command using its row number:

    1. > ls | sort-by name
    2. ───┬───────────────┬──────┬─────────┬────────────
    3. # │ name │ type │ size │ modified
    4. ───┼───────────────┼──────┼─────────┼────────────
    5. 0 files.rs File 4.6 KB 5 days ago
    6. 2 lite_parse.rs File 6.3 KB 5 days ago
    7. 3 parse.rs File 49.8 KB 1 day ago
    8. 4 path.rs File 2.1 KB 5 days ago
    9. 5 shapes.rs File 4.7 KB 5 days ago
    10. 6 signature.rs File 1.2 KB 5 days ago
    11. ───┴───────────────┴──────┴─────────┴────────────
    12. > ls | sort-by name | select 5
    13. ───┬───────────────┬──────┬─────────┬────────────
    14. # │ name │ type │ size │ modified
    15. ───┼───────────────┼──────┼─────────┼────────────
    16. 0 shapes.rs File 4.7 KB 5 days ago
    17. ───┴───────────────┴──────┴─────────┴────────────
    1. > ls | get name
    2. ───┬───────────────
    3. 0 files.rs
    4. 1 lib.rs
    5. 2 lite_parse.rs
    6. 3 parse.rs
    7. 4 path.rs
    8. 5 shapes.rs
    9. 6 signature.rs
    10. ───┴───────────────

    We now have the values for each of the filenames.

    This might look like the select command we saw earlier, so let’s put that here as well to compare the two:

    These look very similar! Let’s see if we can spell out the difference between these two commands to make it clear:

    • - creates a new table which includes only the columns specified
    • get - returns the values inside the column specified as a list

    The one way to tell these apart looking at the table is that the column names are missing, which lets us know that this is going to be a list of values we can work with.

    The command can go one step further and take a path to data deeper in the table. This simplifies working with more complex data, like the structures you might find in a .json file.

    In addition to selecting data from a table, we can also update what the table has. We may want to combine tables, add new columns, or edit the contents of a cell. In Nu, rather than editing in place, each of the commands in the section will return a new table in the pipeline.

    We can concatenate tables with identical column names using append:

    1. > let $first = [[a b]; [1 2]]
    2. > let $second = [[a b]; [3 4]]
    3. > $first | append $second
    4. ───┬───┬───
    5. # │ a │ b
    6. ───┼───┼───
    7. 0 1 2
    8. 1 3 4
    9. ───┴───┴───

    Merging Tables

    We can use the merge command to merge two (or more) tables together

    1. > let $first = [[a b]; [1 2]]
    2. > let $second = [[c d]; [3 4]]
    3. > $first | merge { $second }
    4. ───┬───┬───┬───┬───
    5. # │ a │ b │ c │ d
    6. ───┼───┼───┼───┼───
    7. 0 1 2 3 4
    8. ───┴───┴───┴───┴───

    Let’s add a third table:

    1. > let $third = [[e f]; [5 6]]
    1. > $first | merge { $second } | merge { $third }
    2. ───┬───┬───┬───┬───┬───┬───
    3. ───┼───┼───┼───┼───┼───┼───
    4. 0 1 2 3 4 5 6
    5. ───┴───┴───┴───┴───┴───┴───

    Or we could use the command to dynamically merge all tables:

    1. > [$first $second $third] | reduce {|it, acc| $acc|merge { $it }}
    2. ───┬───┬───┬───┬───┬───┬───
    3. ───┼───┼───┼───┼───┼───┼───
    4. 0 1 2 3 4 5 6
    5. ───┴───┴───┴───┴───┴───┴───

    We can use the insert command to add a new column to the table. Let’s look at an example:

    1. > open rustfmt.toml
    2. ─────────┬──────
    3. edition 2018
    4. ─────────┴──────

    Let’s add a column called “next_edition” with the value 2021:

    Notice that we if open the original file, the contents have stayed the same:

    1. > open rustfmt.toml
    2. ─────────┬──────
    3. edition 2018
    4. ─────────┴──────

    Changes in Nu are functional changes, meaning that they work on the values themselves rather than trying to cause a permanent change. This lets us do many different types of work in our pipeline until we’re ready to write out the result with any changes we’d like if we choose to. Here we could write out the result using the command:

    1. > open rustfmt.toml | insert next_edition 2021 | save rustfmt2.toml
    2. > open rustfmt2.toml
    3. ──────────────┬──────
    4. edition 2018
    5. next_edition 2021
    6. ──────────────┴──────

    Updating a column

    In a similar way to the command, we can also use the update command to change the contents of a column to a new value. To see it in action let’s open the same file:

    1. > open rustfmt.toml
    2. ─────────┬──────
    3. edition 2018
    4. ─────────┴──────

    And now, let’s update the edition to point at the next edition we hope to support:

    1. > open rustfmt.toml | update edition 2021
    2. ─────────┬──────
    3. edition 2021
    4. ─────────┴──────

    You can also use the command to insert or update depending on whether the column already exists.

    You can use move to move columns in the table. For example, if we wanted to move the “name” column from ls after the “size” column, we could do:

    1. > ls | move name --after size
    2. ╭────┬──────┬─────────┬───────────────────┬──────────────╮
    3. # │ type │ size │ name │ modified │
    4. ├────┼──────┼─────────┼───────────────────┼──────────────┤
    5. 0 dir 256 B Applications 3 days ago
    6. 1 dir 256 B Data 2 weeks ago
    7. 2 dir 448 B Desktop 2 hours ago
    8. 3 dir 192 B Disks a week ago
    9. 4 dir 416 B Documents 4 days ago
    10. ...

    Renaming columns

    1. > ls | rename filename filetype filesize date
    2. ╭────┬───────────────────┬──────────┬──────────┬──────────────╮
    3. # │ filename │ filetype │ filesize │ date │
    4. ├────┼───────────────────┼──────────┼──────────┼──────────────┤
    5. 0 Applications dir 256 B 3 days ago
    6. 1 Data dir 256 B 2 weeks ago
    7. 2 Desktop dir 448 B 2 hours ago
    8. 3 Disks dir 192 B a week ago
    9. 4 Documents dir 416 B 4 days ago
    10. ...