Ir al contenido

Nushell

Shell moderno de datos estructurados que trata la salida de comandos como tablas y soporta pipelines con datos tipados, filtrado y scripting multiplataforma.

Instalación

ComandoDescripción
brew install nushellInstalar en macOS con Homebrew
cargo install nuInstalar desde crates.io
winget install nushellInstalar en Windows con winget
sudo apt install nushellInstalar en Debian/Ubuntu
pacman -S nushellInstalar en Arch Linux
nix-env -i nushellInstalar en NixOS
nuIniciar Nushell
nu --versionMostrar la versión instalada
nu -c "ls"Ejecutar un solo comando y salir
nu script.nuEjecutar un archivo de script Nushell
chsh -s /usr/bin/nuEstablecer Nushell como shell predeterminado

Comandos Básicos

Información del Sistema

ComandoDescripción
sysMostrar información completa del sistema
sys hostMostrar detalles del host (nombre, SO, kernel)
sys memMostrar uso de memoria
sys cpuMostrar información de la CPU
sys disksMostrar uso de disco
sys netMostrar interfaces de red
sys tempMostrar sensores de temperatura
date nowMostrar fecha y hora actual
date now | format date "%Y-%m-%d"Formatear la fecha actual
$nu.home-pathMostrar la ruta del directorio home
$nu.os-infoMostrar detalles del SO

Listado de Archivos

ComandoDescripción
lsListar archivos como tabla estructurada
ls -lListado largo con detalles
ls -aMostrar archivos ocultos
ls **/*.rsGlob recursivo para archivos Rust
ls | where size > 1mbFiltrar archivos mayores de 1MB
ls | where type == dirFiltrar solo directorios
ls | sort-by modified -rOrdenar por fecha de modificación (más reciente primero)
ls | sort-by size -rOrdenar por tamaño descendente
ls | get nameObtener solo la columna de nombres de archivo

Gestión de Procesos

ComandoDescripción
psListar procesos como tabla
ps | where cpu > 10Encontrar procesos usando >10% de CPU
ps | where name =~ "node"Encontrar procesos por patrón de nombre
ps | sort-by mem -r | first 10Top 10 procesos por memoria
ps | where pid == 1234Encontrar proceso por PID

Sistema de Ayuda

ComandoDescripción
helpMostrar ayuda general
help commandsListar todos los comandos disponibles
help lsMostrar ayuda para un comando específico
help operatorsListar operadores disponibles
help escapesMostrar secuencias de escape de cadenas

Pipeline y Filtros

Operaciones con Tablas

ComandoDescripción
ls | select name sizeSeleccionar columnas específicas
ls | reject modifiedEliminar columnas específicas
ls | rename filename filesizeRenombrar columnas
ls | first 5Obtener las primeras 5 filas
ls | last 3Obtener las últimas 3 filas
ls | skip 10Saltar las primeras 10 filas
ls | lengthContar número de filas
ls | reverseInvertir el orden de filas
ls | shuffleAleatorizar el orden de filas
ls | flattenAplanar tablas anidadas
ls | columnsListar nombres de columnas

Filtrado y Ordenamiento

ComandoDescripción
ls | where size > 1mbFiltrar por comparación
ls | where name =~ "test"Filtrar por coincidencia regex
ls | where name starts-with "src"Filtrar por prefijo
ls | where name ends-with ".md"Filtrar por sufijo
ls | where type in ["file" "dir"]Filtrar por lista de valores
ls | sort-by size -rOrdenar descendente
ls | sort-by name -iOrdenar sin distinción de mayúsculas
ls | uniq-by typeEliminar duplicados por columna
ls | group-by typeAgrupar filas por valor de columna

Transformación

ComandoDescripción
ls | each { |it| $it.name }Transformar cada fila
ls | par-each { |it| $it.name }Transformar en paralelo
ls | update size { |it| $it.size / 1kb }Actualizar valores de columna
ls | insert label { |it| $it.name + "-file" }Agregar nueva columna
ls | reduce -f 0 { |it, acc| $acc + $it.size }Acumular valores
ls | enumerateAgregar columna de índice
ls | window 3Ventana deslizante de 3 filas
ls | zip [1 2 3]Combinar con otra lista
ls | transposeIntercambiar filas y columnas

Tipos de Datos

Primitivos

ComandoDescripción
42Entero
3.14Flotante
"hello"Cadena de texto
true / falseBooleano
nullValor nulo
2024-01-15Fecha
5sec / 3min / 2hrDuración
1kb / 5mb / 2gbTamaño de archivo
0b1010Literal binario
0xffLiteral hexadecimal

Colecciones

ComandoDescripción
[1 2 3]Lista
[1 2 3] | append 4Agregar al final de la lista
[1 2 3] | prepend 0Agregar al inicio de la lista
{name: "Alice", age: 30}Registro
{a: 1} | merge {b: 2}Fusionar registros
[[name age]; ["Alice" 30] ["Bob" 25]]Literal de tabla
0..9Rango (0 a 9)
0..<9Rango exclusivo (0 a 8)
0..2..10Rango con paso (0, 2, 4, 6, 8, 10)

Conversiones de Tipo

ComandoDescripción
"42" | into intCadena a entero
"3.14" | into floatCadena a flotante
42 | into stringNúmero a cadena
"true" | into boolCadena a booleano
"2024-01-15" | into datetimeCadena a fecha y hora
1024 | into filesizeNúmero a tamaño de archivo
5 | into duration --unit secNúmero a duración
42 | into binaryNúmero a binario
[1 2 3] | into recordLista a registro
{a: 1} | into recordConvertir a registro

Trabajo con Archivos

Apertura y Análisis

ComandoDescripción
open data.jsonAbrir y analizar archivo JSON
open data.csvAbrir y analizar archivo CSV
open data.yamlAbrir y analizar archivo YAML
open data.tomlAbrir y analizar archivo TOML
open data.xmlAbrir y analizar archivo XML
open data.tsvAbrir y analizar archivo TSV
open data.sqliteAbrir base de datos SQLite
open file.txtAbrir como texto plano
open data.json | get usersAbrir y navegar dentro de los datos

Guardar y Convertir

ComandoDescripción
"hello" | save hello.txtGuardar cadena en archivo
ls | save files.jsonGuardar tabla como JSON
ls | save files.csvGuardar tabla como CSV
ls | save files.yamlGuardar tabla como YAML
open data.json | to csvConvertir JSON a CSV
open data.csv | to jsonConvertir CSV a JSON
open data.json | save data.yamlConvertir entre formatos
open data.csv | save -f data.csvForzar sobrescritura de archivo existente
"line1\nline2" | save -a log.txtAgregar al final de un archivo

Manipulación de Archivos

ComandoDescripción
open file.txt | linesDividir archivo en líneas
open file.txt | lines | lengthContar líneas en archivo
open file.csv | where status == "active"Filtrar filas de CSV
open file.json | select name emailSeleccionar campos de JSON
open file.json | to yaml | save file.yamlConvertir JSON a YAML
glob "**/*.md" | each { |f| open $f }Abrir todos los archivos que coincidan

Operaciones con Cadenas

Mayúsculas/Minúsculas y Formato

ComandoDescripción
"hello world" | str upcaseConvertir a mayúsculas
"HELLO" | str downcaseConvertir a minúsculas
"hello" | str capitalizeCapitalizar primera letra
" hello " | str trimRecortar espacios en blanco
"hello" | str trim --char "h"Recortar carácter específico
"hello" | str reverseInvertir cadena

Búsqueda y Reemplazo

ComandoDescripción
"hello world" | str replace "world" "nu"Reemplazar primera ocurrencia
"aabaa" | str replace -a "a" "x"Reemplazar todas las ocurrencias
"hello world" | str replace -r '\w+' 'word'Reemplazar con regex
"hello world" | str contains "world"Verificar si la cadena contiene
"hello world" | str starts-with "hello"Verificar prefijo
"hello world" | str ends-with "world"Verificar sufijo
"hello world" | str index-of "world"Encontrar posición de subcadena

División y Unión

ComandoDescripción
"hello world" | split row " "Dividir por delimitador
"a,b,c" | split row ","Dividir cadena estilo CSV
"hello" | split charsDividir en caracteres
["hello" "world"] | str join " "Unir lista en cadena
["a" "b" "c"] | str join ","Unir con coma
"hello" | str lengthObtener longitud de cadena
"hello world" | str substring 0..5Extraer subcadena

Interpolación de Cadenas

# Interpolación básica
let name = "World"
$"Hello, ($name)!"

# Interpolación de expresiones
$"Total: (1 + 2 + 3)"

# Cadenas multilínea
$"Line 1
Line 2
Line 3"

# Cadenas sin procesar (sin escapes)
r#'C:\Users\path'#

Comandos Personalizados

Definición de Funciones

ComandoDescripción
def greet [name: string] { $"Hello, ($name)!" }Comando personalizado básico
def add [a: int, b: int] -> int { $a + $b }Comando con anotaciones de tipo
def greet [name = "World"] { ... }Comando con parámetro por defecto
def "git branches" [] { git branch | lines }Nombre estilo subcomando
def --wrapped cmd [...rest] { ... }Aceptar argumentos extra

Variables y Flujo de Control

ComandoDescripción
let x = 42Variable inmutable
mut x = 0; $x = $x + 1Variable mutable
const PI = 3.14159Constante en tiempo de compilación
if $x > 0 { "pos" } else { "neg" }Expresión condicional
match $x { 1 => "one", 2 => "two", _ => "other" }Coincidencia de patrones
for item in [1 2 3] { print $item }Bucle for
while $x < 10 { $x = $x + 1 }Bucle while
loop { if $x > 10 { break }; $x += 1 }Bucle infinito con break
try { risky_op } catch { "failed" }Manejo de errores

Funciones Avanzadas

# Función con parámetro de bandera
def greet [
  name: string       # Nombre para saludar
  --excited (-e)     # Usar signo de exclamación
] {
  if $excited {
    $"Hello, ($name)!"
  } else {
    $"Hello, ($name)."
  }
}

# Función con parámetros rest
def sum [...nums: int] -> int {
  $nums | math sum
}

# Función con entrada de pipeline
def double-all [] {
  each { |x| $x * 2 }
}
# Uso: [1 2 3] | double-all

Matemáticas y Agregación

ComandoDescripción
[1 2 3 4 5] | math sumSuma de valores
[1 2 3 4 5] | math avgPromedio de valores
[1 2 3 4 5] | math minValor mínimo
[1 2 3 4 5] | math maxValor máximo
[1 2 3 4 5] | math medianValor mediano
[1 2 3 4 5] | math stddevDesviación estándar
[1 2 3 4 5] | math varianceVarianza
[1 2 3] | math productProducto de valores
10 | math absValor absoluto
10 | math sqrtRaíz cuadrada
2 | math round -p 2Redondear a precisión
10 | math log 2Logaritmo base 2

HTTP y Redes

ComandoDescripción
http get https://api.example.com/dataSolicitud GET
http post https://api.example.com/data {name: "test"}Solicitud POST con JSON
http put https://api.example.com/data/1 {name: "updated"}Solicitud PUT
http delete https://api.example.com/data/1Solicitud DELETE
http get url --headers [Accept application/json]GET con encabezados personalizados
http get url | get dataGET y extraer campo
port 8080Verificar si un puerto está en uso

Ejemplo HTTP

# Obtener y procesar API JSON
let users = (http get "https://jsonplaceholder.typicode.com/users")
$users | select name email | first 5

# POST con encabezados y cuerpo
http post "https://api.example.com/items" {
  name: "New Item"
  price: 29.99
} --headers [Authorization $"Bearer ($env.API_TOKEN)"]

Configuración

Rutas de Configuración

ComandoDescripción
$nu.config-pathMostrar ruta del archivo de configuración
$nu.env-pathMostrar ruta del archivo de configuración de entorno
$nu.default-config-dirMostrar directorio de configuración
config nuAbrir configuración en el editor
config envAbrir configuración de entorno en el editor

Ajustes de Configuración

ComandoDescripción
$env.config.show_banner = falseDesactivar banner de inicio
$env.config.buffer_editor = "vim"Establecer editor para Ctrl+O
$env.config.history.file_format = "sqlite"Usar historial SQLite
$env.config.history.max_size = 100_000Establecer máximo de entradas de historial
$env.config.completions.external.enable = trueActivar completado externo
$env.config.cursor_shape.emacs = "line"Establecer forma del cursor
$env.config.footer_mode = "25"Mostrar pie de página para tablas grandes
$env.config.table.mode = "rounded"Establecer estilo de borde de tabla

Entorno y PATH

ComandoDescripción
$env.PATH = ($env.PATH | prepend "/usr/local/bin")Agregar al PATH
$env.PATH = ($env.PATH | append "~/.local/bin")Agregar al final del PATH
$env.EDITOR = "vim"Establecer variable de entorno
alias ll = ls -lCrear alias de comando
source ~/.config/nushell/custom.nuCargar configuración adicional

Ejemplo de Configuración

# env.nu — configuración de entorno
$env.PATH = ($env.PATH | split row (char esep)
  | prepend "/usr/local/bin"
  | prepend ($env.HOME | path join ".cargo" "bin")
  | append ($env.HOME | path join "go" "bin")
)

$env.EDITOR = "nvim"
$env.VISUAL = "nvim"
$env.PAGER = "less"
# config.nu — configuración del shell
$env.config = {
  show_banner: false
  buffer_editor: "nvim"
  table: {
    mode: rounded
    index_mode: auto
    trim: {
      methodology: wrapping
      wrapping_try_keep_words: true
    }
  }
  history: {
    file_format: "sqlite"
    max_size: 100_000
    sync_on_enter: true
    isolation: false
  }
  completions: {
    case_sensitive: false
    quick: true
    partial: true
    algorithm: "prefix"
    external: {
      enable: true
      max_results: 100
    }
  }
}

Módulos y Overlays

ComandoDescripción
module greet { export def hello [] { "hi" } }Definir un módulo en línea
use greet helloImportar comando desde módulo
use greet *Importar todo desde módulo
use utils.nuImportar desde archivo de módulo
overlay use spamActivar overlay
overlay hide spamDesactivar overlay
overlay listListar overlays activos

Ejemplo de Módulo

# archivo: utils.nu
export def "str kebab" [] {
  $in | str downcase | str replace -a " " "-"
}

export def "str title" [] {
  $in | split row " "
  | each { |w| $w | str capitalize }
  | str join " "
}

# Uso:
# use utils.nu
# "Hello World" | str kebab    # "hello-world"
# "hello world" | str title    # "Hello World"

Operaciones de Base de Datos

ComandoDescripción
open data.dbAbrir base de datos SQLite
open data.db | query db "SELECT * FROM users"Ejecutar consulta SQL
open data.db | query db "SELECT * FROM users WHERE age > 30"Consulta filtrada
open data.db | schemaMostrar esquema de base de datos
[[name age]; ["Alice" 30]] | into sqlite data.dbCrear SQLite desde tabla
ls | into sqlite -t files data.dbGuardar tabla en SQLite

Sistema de Plugins

ComandoDescripción
plugin listListar plugins instalados
plugin add /path/to/pluginRegistrar un plugin
plugin rm plugin_nameEliminar un plugin
plugin use plugin_nameCargar un plugin
cargo install nu_plugin_formatsInstalar plugin de formatos
cargo install nu_plugin_queryInstalar plugin de consultas
cargo install nu_plugin_gstatInstalar plugin de estado git

Mejores Prácticas

  1. Usar datos estructurados — Nushell brilla cuando se trabaja con tablas y registros en lugar de cadenas de texto sin formato. Usa select, where y sort-by en lugar de grep y awk.

  2. Tipar los parámetros de las funciones — Agrega anotaciones de tipo a los comandos personalizados (name: string, count: int) para detectar errores temprano y mejorar el autocompletado.

  3. Preferir variables inmutables — Usa let por defecto y solo usa mut cuando realmente necesites mutación. Esto previene cambios de estado accidentales en los scripts.

  4. Usar historial SQLite — Configura $env.config.history.file_format = "sqlite" para búsquedas más rápidas, mejor resistencia a la corrupción y metadatos más ricos.

  5. Aprovechar par-each para rendimiento — Al procesar muchos elementos de forma independiente, par-each se ejecuta en hilos paralelos y puede ser significativamente más rápido que each.

  6. Usar módulos para código reutilizable — Organiza los comandos personalizados en archivos de módulo .nu y usa use en lugar de source. Los módulos tienen namespacing y exportaciones adecuados.

  7. Usar into para conversiones de tipo — Siempre usa conversión explícita de tipo (into int, into string, etc.) en lugar de confiar en la coerción implícita para scripts confiables.

  8. Configurar completados — Activa los completados externos y carapace para soporte de completado en todas las herramientas CLI.

  9. Usar interpolación de cadenas — Prefiere $"Hello, ($name)!" sobre la concatenación de cadenas con + para un código más limpio y legible.

  10. Manejar errores con try/catch — Envuelve las operaciones que pueden fallar (acceso a archivos, HTTP, análisis) en bloques try { } catch { } para scripts robustos.

  11. Probar con describe — Usa expression | describe para inspeccionar el tipo de cualquier valor durante el desarrollo y la depuración.

  12. Usar closures de forma consistente — Los closures de Nushell usan la sintaxis { |params| body }. Siempre incluye los caracteres pipe incluso para parámetros únicos por claridad.