nushell / nushell

A new type of shell
https://www.nushell.sh/
MIT License
32.42k stars 1.67k forks source link

compact --empty doesn't work on columns #11164

Open xd003 opened 11 months ago

xd003 commented 11 months ago

Describe the bug

i am simply trying to reject the target column if its empty as its quite often that i don't have any symlinks in my current directory and i see empty target column too often

How to reproduce

ls -l | compact --empty doesn't seem to reject the empty target column when executed in a directory not containing any symlinks

Expected behavior

I am assuming compact --empty is intended to work on columns as well since i couldn't find anything specific for columns to achieve this behaviour

Configuration

key value
version 0.87.1
branch
commit_hash 3d631490bc17cfef2944072f9b7869cd9cac1e7b
build_os windows-x86_64
build_target x86_64-pc-windows-msvc
rust_version rustc 1.71.1 (eb26296b5 2023-08-03)
rust_channel 1.71.1-x86_64-pc-windows-msvc
cargo_version cargo 1.71.1 (7f1d04c00 2023-07-29)
build_time 2023-11-18 18:55:24 +00:00
build_rust_channel release
allocator mimalloc
features default, sqlite, trash, which, zip
installed_plugins

Additional context

No response

fdncred commented 11 months ago

The problem with having a command that analyzes columns to determine if they're empty and then remove them is that it doesn't work with streaming. Nushell supports infinite streams. You can't automatically delete columns like this with infinite streams. You'd have to collect the entire table and then analyze it and then delete the columns. It may be more efficient to just do pipeline | reject empty_column manually.

Having said that, if there was a compact columns command that worked the same way as compact but collected the table, we may accept a PR for it. It would just have to be very clear that streaming is not supported and it collects the data prior to analysis and removal.

Mrfiregem commented 3 months ago

For anyone looking to have this for their scripts like I did, here's it is as a nushell function

def "compact column" [
    --empty (-e) # Also compact empty items like "", {}, and []
    ...rest: string # The columns to compact from the table
] {
    mut result = $in
    let cols = if ($rest | length) > 0 { $rest } else { $result | columns }

    for col in $cols {
        if ($result | get $col | compact --empty=$empty | length) == 0 {
            $result = ($result | reject $col)
        }
    }

    return $result
}