명령 출력을 테이블로 처리하고 타입이 지정된 데이터, 필터링, 크로스 플랫폼 스크립팅을 지원하는 파이프라인을 갖춘 현대적 구조화 데이터 셸.
| 명령어 | 설명 |
|---|
brew install nushell | macOS에서 Homebrew로 설치 |
cargo install nu | crates.io에서 설치 |
winget install nushell | Windows에서 winget으로 설치 |
sudo apt install nushell | Debian/Ubuntu에서 설치 |
pacman -S nushell | Arch Linux에서 설치 |
nix-env -i nushell | NixOS에서 설치 |
nu | Nushell 실행 |
nu --version | 설치된 버전 확인 |
nu -c "ls" | 단일 명령 실행 후 종료 |
nu script.nu | Nushell 스크립트 파일 실행 |
chsh -s /usr/bin/nu | Nushell을 기본 셸로 설정 |
| 명령어 | 설명 |
|---|
sys | 전체 시스템 정보 표시 |
sys host | 호스트 상세 정보 표시 (이름, OS, 커널) |
sys mem | 메모리 사용량 표시 |
sys cpu | CPU 정보 표시 |
sys disks | 디스크 사용량 표시 |
sys net | 네트워크 인터페이스 표시 |
sys temp | 온도 센서 표시 |
date now | 현재 날짜 및 시간 표시 |
date now | format date "%Y-%m-%d" | 현재 날짜 포맷팅 |
$nu.home-path | 홈 디렉토리 경로 표시 |
$nu.os-info | OS 상세 정보 표시 |
| 명령어 | 설명 |
|---|
ls | 구조화된 테이블로 파일 목록 표시 |
ls -l | 상세 정보와 함께 긴 목록 표시 |
ls -a | 숨김 파일 표시 |
ls **/*.rs | Rust 파일에 대한 재귀적 glob |
ls | where size > 1mb | 1MB보다 큰 파일 필터링 |
ls | where type == dir | 디렉토리만 필터링 |
ls | sort-by modified -r | 수정 날짜순 정렬 (최신 우선) |
ls | sort-by size -r | 크기 내림차순 정렬 |
ls | get name | 파일 이름 열만 가져오기 |
| 명령어 | 설명 |
|---|
ps | 프로세스를 테이블로 표시 |
ps | where cpu > 10 | CPU 10% 초과 사용 프로세스 찾기 |
ps | where name =~ "node" | 이름 패턴으로 프로세스 찾기 |
ps | sort-by mem -r | first 10 | 메모리 기준 상위 10개 프로세스 |
ps | where pid == 1234 | PID로 프로세스 찾기 |
| 명령어 | 설명 |
|---|
help | 일반 도움말 표시 |
help commands | 사용 가능한 모든 명령어 나열 |
help ls | 특정 명령어에 대한 도움말 표시 |
help operators | 사용 가능한 연산자 나열 |
help escapes | 문자열 이스케이프 시퀀스 표시 |
| 명령어 | 설명 |
|---|
ls | select name size | 특정 열 선택 |
ls | reject modified | 특정 열 제거 |
ls | rename filename filesize | 열 이름 변경 |
ls | first 5 | 처음 5개 행 가져오기 |
ls | last 3 | 마지막 3개 행 가져오기 |
ls | skip 10 | 처음 10개 행 건너뛰기 |
ls | length | 행 수 세기 |
ls | reverse | 행 순서 뒤집기 |
ls | shuffle | 행 순서 무작위화 |
ls | flatten | 중첩 테이블 평탄화 |
ls | columns | 열 이름 나열 |
| 명령어 | 설명 |
|---|
ls | where size > 1mb | 비교로 필터링 |
ls | where name =~ "test" | 정규식 매칭으로 필터링 |
ls | where name starts-with "src" | 접두사로 필터링 |
ls | where name ends-with ".md" | 접미사로 필터링 |
ls | where type in ["file" "dir"] | 값 목록으로 필터링 |
ls | sort-by size -r | 내림차순 정렬 |
ls | sort-by name -i | 대소문자 구분 없이 정렬 |
ls | uniq-by type | 열 기준 중복 제거 |
ls | group-by type | 열 값 기준으로 행 그룹화 |
| 명령어 | 설명 |
|---|
ls | each { |it| $it.name } | 각 행 변환 |
ls | par-each { |it| $it.name } | 병렬로 변환 |
ls | update size { |it| $it.size / 1kb } | 열 값 업데이트 |
ls | insert label { |it| $it.name + "-file" } | 새 열 추가 |
ls | reduce -f 0 { |it, acc| $acc + $it.size } | 값 누적 |
ls | enumerate | 인덱스 열 추가 |
ls | window 3 | 3개 행 슬라이딩 윈도우 |
ls | zip [1 2 3] | 다른 리스트와 합치기 |
ls | transpose | 행과 열 교환 |
| 명령어 | 설명 |
|---|
42 | 정수 |
3.14 | 부동소수점 |
"hello" | 문자열 |
true / false | 불리언 |
null | Null 값 |
2024-01-15 | 날짜 |
5sec / 3min / 2hr | 기간 |
1kb / 5mb / 2gb | 파일 크기 |
0b1010 | 이진 리터럴 |
0xff | 16진수 리터럴 |
| 명령어 | 설명 |
|---|
[1 2 3] | 리스트 |
[1 2 3] | append 4 | 리스트에 추가 |
[1 2 3] | prepend 0 | 리스트 앞에 추가 |
{name: "Alice", age: 30} | 레코드 |
{a: 1} | merge {b: 2} | 레코드 병합 |
[[name age]; ["Alice" 30] ["Bob" 25]] | 테이블 리터럴 |
0..9 | 범위 (0~9) |
0..<9 | 배타적 범위 (0~8) |
0..2..10 | 단계가 있는 범위 (0, 2, 4, 6, 8, 10) |
| 명령어 | 설명 |
|---|
"42" | into int | 문자열을 정수로 |
"3.14" | into float | 문자열을 부동소수점으로 |
42 | into string | 숫자를 문자열로 |
"true" | into bool | 문자열을 불리언으로 |
"2024-01-15" | into datetime | 문자열을 날짜/시간으로 |
1024 | into filesize | 숫자를 파일 크기로 |
5 | into duration --unit sec | 숫자를 기간으로 |
42 | into binary | 숫자를 바이너리로 |
[1 2 3] | into record | 리스트를 레코드로 |
{a: 1} | into record | 레코드로 변환 |
| 명령어 | 설명 |
|---|
open data.json | JSON 파일 열기 및 파싱 |
open data.csv | CSV 파일 열기 및 파싱 |
open data.yaml | YAML 파일 열기 및 파싱 |
open data.toml | TOML 파일 열기 및 파싱 |
open data.xml | XML 파일 열기 및 파싱 |
open data.tsv | TSV 파일 열기 및 파싱 |
open data.sqlite | SQLite 데이터베이스 열기 |
open file.txt | 일반 텍스트로 열기 |
open data.json | get users | 파일 열고 데이터 탐색 |
| 명령어 | 설명 |
|---|
"hello" | save hello.txt | 문자열을 파일에 저장 |
ls | save files.json | 테이블을 JSON으로 저장 |
ls | save files.csv | 테이블을 CSV로 저장 |
ls | save files.yaml | 테이블을 YAML로 저장 |
open data.json | to csv | JSON을 CSV로 변환 |
open data.csv | to json | CSV를 JSON으로 변환 |
open data.json | save data.yaml | 포맷 간 변환 |
open data.csv | save -f data.csv | 기존 파일 강제 덮어쓰기 |
"line1\nline2" | save -a log.txt | 파일에 추가 |
| 명령어 | 설명 |
|---|
open file.txt | lines | 파일을 줄 단위로 분할 |
open file.txt | lines | length | 파일의 줄 수 세기 |
open file.csv | where status == "active" | CSV 행 필터링 |
open file.json | select name email | JSON에서 필드 선택 |
open file.json | to yaml | save file.yaml | JSON을 YAML로 변환 |
glob "**/*.md" | each { |f| open $f } | 일치하는 모든 파일 열기 |
| 명령어 | 설명 |
|---|
"hello world" | str upcase | 대문자로 변환 |
"HELLO" | str downcase | 소문자로 변환 |
"hello" | str capitalize | 첫 글자 대문자화 |
" hello " | str trim | 공백 제거 |
"hello" | str trim --char "h" | 특정 문자 제거 |
"hello" | str reverse | 문자열 뒤집기 |
| 명령어 | 설명 |
|---|
"hello world" | str replace "world" "nu" | 첫 번째 항목 치환 |
"aabaa" | str replace -a "a" "x" | 모든 항목 치환 |
"hello world" | str replace -r '\w+' 'word' | 정규식으로 치환 |
"hello world" | str contains "world" | 문자열 포함 여부 확인 |
"hello world" | str starts-with "hello" | 접두사 확인 |
"hello world" | str ends-with "world" | 접미사 확인 |
"hello world" | str index-of "world" | 부분 문자열 위치 찾기 |
| 명령어 | 설명 |
|---|
"hello world" | split row " " | 구분자로 분할 |
"a,b,c" | split row "," | CSV 스타일 문자열 분할 |
"hello" | split chars | 문자 단위로 분할 |
["hello" "world"] | str join " " | 리스트를 문자열로 결합 |
["a" "b" "c"] | str join "," | 쉼표로 결합 |
"hello" | str length | 문자열 길이 가져오기 |
"hello world" | str substring 0..5 | 부분 문자열 추출 |
# 기본 보간
let name = "World"
$"Hello, ($name)!"
# 표현식 보간
$"Total: (1 + 2 + 3)"
# 여러 줄 문자열
$"Line 1
Line 2
Line 3"
# 원시 문자열 (이스케이프 없음)
r#'C:\Users\path'#
| 명령어 | 설명 |
|---|
def greet [name: string] { $"Hello, ($name)!" } | 기본 사용자 정의 명령 |
def add [a: int, b: int] -> int { $a + $b } | 타입 어노테이션이 있는 명령 |
def greet [name = "World"] { ... } | 기본 매개변수가 있는 명령 |
def "git branches" [] { git branch | lines } | 하위 명령 스타일 이름 |
def --wrapped cmd [...rest] { ... } | 추가 인수 허용 |
| 명령어 | 설명 |
|---|
let x = 42 | 불변 변수 |
mut x = 0; $x = $x + 1 | 가변 변수 |
const PI = 3.14159 | 컴파일 타임 상수 |
if $x > 0 { "pos" } else { "neg" } | 조건식 |
match $x { 1 => "one", 2 => "two", _ => "other" } | 패턴 매칭 |
for item in [1 2 3] { print $item } | for 루프 |
while $x < 10 { $x = $x + 1 } | while 루프 |
loop { if $x > 10 { break }; $x += 1 } | break가 있는 무한 루프 |
try { risky_op } catch { "failed" } | 에러 처리 |
# 플래그 매개변수가 있는 함수
def greet [
name: string # 인사할 이름
--excited (-e) # 느낌표 사용
] {
if $excited {
$"Hello, ($name)!"
} else {
$"Hello, ($name)."
}
}
# 나머지 매개변수가 있는 함수
def sum [...nums: int] -> int {
$nums | math sum
}
# 파이프라인 입력 함수
def double-all [] {
each { |x| $x * 2 }
}
# 사용법: [1 2 3] | double-all
| 명령어 | 설명 |
|---|
[1 2 3 4 5] | math sum | 값의 합계 |
[1 2 3 4 5] | math avg | 값의 평균 |
[1 2 3 4 5] | math min | 최솟값 |
[1 2 3 4 5] | math max | 최댓값 |
[1 2 3 4 5] | math median | 중앙값 |
[1 2 3 4 5] | math stddev | 표준편차 |
[1 2 3 4 5] | math variance | 분산 |
[1 2 3] | math product | 값의 곱 |
10 | math abs | 절대값 |
10 | math sqrt | 제곱근 |
2 | math round -p 2 | 정밀도에 맞게 반올림 |
10 | math log 2 | 밑이 2인 로그 |
| 명령어 | 설명 |
|---|
http get https://api.example.com/data | GET 요청 |
http post https://api.example.com/data {name: "test"} | JSON으로 POST 요청 |
http put https://api.example.com/data/1 {name: "updated"} | PUT 요청 |
http delete https://api.example.com/data/1 | DELETE 요청 |
http get url --headers [Accept application/json] | 커스텀 헤더로 GET |
http get url | get data | GET 후 필드 추출 |
port 8080 | 포트 사용 여부 확인 |
# JSON API 가져오기 및 처리
let users = (http get "https://jsonplaceholder.typicode.com/users")
$users | select name email | first 5
# 헤더와 본문으로 POST
http post "https://api.example.com/items" {
name: "New Item"
price: 29.99
} --headers [Authorization $"Bearer ($env.API_TOKEN)"]
| 명령어 | 설명 |
|---|
$nu.config-path | 설정 파일 경로 표시 |
$nu.env-path | 환경 설정 파일 경로 표시 |
$nu.default-config-dir | 설정 디렉토리 표시 |
config nu | 에디터에서 설정 열기 |
config env | 에디터에서 환경 설정 열기 |
| 명령어 | 설명 |
|---|
$env.config.show_banner = false | 시작 배너 비활성화 |
$env.config.buffer_editor = "vim" | Ctrl+O용 에디터 설정 |
$env.config.history.file_format = "sqlite" | SQLite 히스토리 사용 |
$env.config.history.max_size = 100_000 | 최대 히스토리 항목 설정 |
$env.config.completions.external.enable = true | 외부 자동완성 활성화 |
$env.config.cursor_shape.emacs = "line" | 커서 모양 설정 |
$env.config.footer_mode = "25" | 큰 테이블에 하단 표시 |
$env.config.table.mode = "rounded" | 테이블 테두리 스타일 설정 |
| 명령어 | 설명 |
|---|
$env.PATH = ($env.PATH | prepend "/usr/local/bin") | PATH에 추가 |
$env.PATH = ($env.PATH | append "~/.local/bin") | PATH 뒤에 추가 |
$env.EDITOR = "vim" | 환경 변수 설정 |
alias ll = ls -l | 명령 별칭 생성 |
source ~/.config/nushell/custom.nu | 추가 설정 불러오기 |
# env.nu — 환경 설정
$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 — 셸 설정
$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
}
}
}
| 명령어 | 설명 |
|---|
module greet { export def hello [] { "hi" } } | 인라인 모듈 정의 |
use greet hello | 모듈에서 명령 가져오기 |
use greet * | 모듈에서 모두 가져오기 |
use utils.nu | 파일 모듈에서 가져오기 |
overlay use spam | 오버레이 활성화 |
overlay hide spam | 오버레이 비활성화 |
overlay list | 활성 오버레이 나열 |
# 파일: 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 " "
}
# 사용법:
# use utils.nu
# "Hello World" | str kebab # "hello-world"
# "hello world" | str title # "Hello World"
| 명령어 | 설명 |
|---|
open data.db | SQLite 데이터베이스 열기 |
open data.db | query db "SELECT * FROM users" | SQL 쿼리 실행 |
open data.db | query db "SELECT * FROM users WHERE age > 30" | 필터링된 쿼리 |
open data.db | schema | 데이터베이스 스키마 표시 |
[[name age]; ["Alice" 30]] | into sqlite data.db | 테이블에서 SQLite 생성 |
ls | into sqlite -t files data.db | 테이블을 SQLite에 저장 |
| 명령어 | 설명 |
|---|
plugin list | 설치된 플러그인 나열 |
plugin add /path/to/plugin | 플러그인 등록 |
plugin rm plugin_name | 플러그인 제거 |
plugin use plugin_name | 플러그인 로드 |
cargo install nu_plugin_formats | 포맷 플러그인 설치 |
cargo install nu_plugin_query | 쿼리 플러그인 설치 |
cargo install nu_plugin_gstat | git 상태 플러그인 설치 |
-
구조화된 데이터 사용 — Nushell은 원시 문자열이 아닌 테이블과 레코드로 작업할 때 빛을 발합니다. grep과 awk 대신 select, where, sort-by를 통해 명령을 파이프하세요.
-
함수 매개변수에 타입 지정 — 사용자 정의 명령에 타입 어노테이션(name: string, count: int)을 추가하여 조기에 오류를 잡고 더 나은 자동완성을 활성화하세요.
-
불변 변수 선호 — 기본적으로 let을 사용하고 정말 변경이 필요할 때만 mut을 사용하세요. 이는 스크립트에서 우발적인 상태 변경을 방지합니다.
-
SQLite 히스토리 사용 — 더 빠른 검색, 더 나은 손상 저항성, 더 풍부한 메타데이터를 위해 $env.config.history.file_format = "sqlite"를 설정하세요.
-
성능을 위해 par-each 활용 — 많은 항목을 독립적으로 처리할 때 par-each는 병렬 스레드에서 실행되어 each보다 훨씬 빠를 수 있습니다.
-
재사용 가능한 코드에 모듈 사용 — 사용자 정의 명령을 .nu 모듈 파일로 정리하고 source 대신 use를 사용하세요. 모듈은 적절한 네임스페이싱과 내보내기를 제공합니다.
-
타입 변환에 into 사용 — 안정적인 스크립트를 위해 암시적 변환에 의존하지 말고 항상 명시적 타입 변환(into int, into string 등)을 사용하세요.
-
자동완성 설정 — 모든 CLI 도구에 대한 셸 자동완성 지원을 위해 외부 자동완성과 carapace를 활성화하세요.
-
문자열 보간 사용 — 더 깔끔하고 읽기 쉬운 코드를 위해 +를 사용한 문자열 연결 대신 $"Hello, ($name)!"을 선호하세요.
-
try/catch로 에러 처리 — 실패할 수 있는 작업(파일 접근, HTTP, 파싱)을 강건한 스크립트를 위해 try { } catch { } 블록으로 감싸세요.
-
describe로 테스트 — 개발 및 디버깅 중에 모든 값의 타입을 검사하려면 expression | describe를 사용하세요.
-
클로저를 일관되게 사용 — Nushell 클로저는 { |params| body } 구문을 사용합니다. 명확성을 위해 단일 매개변수에도 항상 파이프 문자를 포함하세요.