Nushell
문서
쿡북
블로그
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
문서
쿡북
블로그
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
  • 소개
  • 설치하기
    • 기본 셸
  • 시작하기
    • 빠른 둘러보기
    • 시스템 이동
    • 누셸 방식으로 생각하기
    • 누셸 치트 시트
  • Nu 기본
    • 데이터 유형
    • 데이터 로드
    • 파이프라인
    • 문자열 작업
    • 목록 작업
    • 레코드 작업
    • 테이블 작업
    • 구조화된 데이터 탐색 및 액세스
    • 특수 변수
  • Nu에서 프로그래밍하기
    • 사용자 지정 명령
    • 별칭
    • 연산자
    • 변수
    • 제어 흐름
    • 스크립트
    • 모듈
      • 모듈 사용하기
      • 모듈 만들기
    • 오버레이
    • 정렬
    • 누셸 코드 테스트
    • 모범 사례
  • 셸로서의 Nu
    • 구성
    • 환경
    • 표준 출력, 표준 오류 및 종료 코드
    • 시스템(외부) 명령 실행
    • 타사 프롬프트 구성 방법
    • 디렉터리 스택
    • Reedline, Nu의 줄 편집기
    • 사용자 지정 완성
    • 외부 명령
    • Nu의 색상 지정 및 테마 설정
    • 후크
    • 백그라운드 작업
  • Nu로 전환하기
    • Bash에서 오신 분들을 위해
    • CMD.EXE에서 오신 분들을 위해
    • 다른 셸 및 도메인 특정 언어의 Nu 맵
    • 명령형 언어의 Nu 맵
    • 함수형 언어의 Nu 맵
    • 누셸 연산자 맵
  • 디자인 노트
    • 누셸 코드가 실행되는 방법
  • (약간)고급 사용법
    • 표준 라이브러리 (미리보기)
    • 데이터프레임
    • 메타데이터
    • 나만의 오류 만들기
    • 병렬 처리
    • 플러그인
    • explore

정렬

누셸은 데이터를 정렬하는 여러 가지 방법을 제공하며, 어떤 방법을 사용할지는 문제와 작업 중인 데이터 종류에 따라 다릅니다. 데이터를 정렬하려는 몇 가지 방법을 살펴보겠습니다.

기본 정렬

목록

기본 목록을 정렬하는 것은 예상대로 작동합니다.

[9 3 8 1 4 6] | sort
# => ╭───┬───╮
# => │ 0 │ 1 │
# => │ 1 │ 3 │
# => │ 2 │ 4 │
# => │ 3 │ 6 │
# => │ 4 │ 8 │
# => │ 5 │ 9 │
# => ╰───┴───╯

그러나 형식을 결합하기 시작하면 상황이 조금 더 복잡해집니다. 예를 들어, 숫자 와 문자열이 포함된 목록이 있는 경우 어떻게 되는지 보겠습니다.

["hello" 4 9 2 1 "foobar" 8 6] | sort
# => ╭───┬────────╮
# => │ 0 │      1 │
# => │ 1 │      2 │
# => │ 2 │      4 │
# => │ 3 │      6 │
# => │ 4 │      8 │
# => │ 5 │      9 │
# => │ 6 │ foobar │
# => │ 7 │ hello  │
# => ╰───┴────────╯

숫자는 순서대로 정렬되고 문자열은 목록 끝으로 정렬되며 순서대로 정렬되는 것을 볼 수 있습니다. 다른 프로그래밍 언어에서 온 경우 이것이 예상과 다를 수 있습니다. 누셸에서는 일반적으로 데이터는 항상 오류 없이 정렬될 수 있습니다.

팁

다른 유형이 포함된 정렬이 오류를 발생시키기를 원하는 경우 엄격한 정렬을 참조하십시오.

누셸의 정렬은 또한 안정적이므로 동일한 값은 서로에 대한 원래 순서를 유지합니다. 이것은 대소문자를 구분하지 않는 정렬 옵션을 사용하여 여기에 설명되어 있습니다.

["foo" "FOO" "BAR" "bar"] | sort -i
# => ╭───┬─────╮
# => │ 0 │ BAR │
# => │ 1 │ bar │
# => │ 2 │ foo │
# => │ 3 │ FOO │
# => ╰───┴─────╯

이 정렬은 대소문자를 구분하지 않으므로 foo와 FOO는 서로 동일한 것으로 간주되며 bar와 BAR도 마찬가지입니다. 결과적으로 대문자 BAR는 입력에서 대문자 BAR가 소문자 bar 앞에 오기 때문에 소문자 bar 앞에 옵니다. 마찬가지로 소문자 foo는 입력과 결과 모두에서 대문자 FOO 앞에 옵니다.

레코드

레코드는 키와 값의 두 가지 방법으로 정렬할 수 있습니다. 기본적으로 레코드를 sort에 전달하면 키 순서로 정렬됩니다.

{x: 123, a: hello!, foo: bar} | sort
# => ╭─────┬────────╮
# => │ a   │ hello! │
# => │ foo │ bar    │
# => │ x   │ 123    │
# => ╰─────┴────────╯

대신 값 순서로 정렬하려면 -v 플래그를 사용하십시오.

{x: 123, a: hello! foo: bar} | sort -v
# => ╭─────┬────────╮
# => │ x   │ 123    │
# => │ foo │ bar    │
# => │ a   │ hello! │
# => ╰─────┴────────╯

테이블

테이블 행은 열 순서대로 행을 비교하여 정렬됩니다. 두 행의 첫 번째 열 값이 같으면 두 번째 열로 정렬됩니다. 행이 다르게 정렬되거나 모든 열이 같을 때까지 반복됩니다.

let items = [
    {id: 100, quantity: 10, price: 5 }
    {id: 100, quantity: 5,  price: 8 }
    {id: 100, quantity: 5,  price: 1 }
]
$items | sort
# => ╭───┬─────┬──────────┬───────╮
# => │ # │ id  │ quantity │ price │
# => ├───┼─────┼──────────┼───────┤
# => │ 0 │ 100 │        5 │     1 │
# => │ 1 │ 100 │        5 │     8 │
# => │ 2 │ 100 │       10 │     5 │
# => ╰───┴─────┴──────────┴───────╯

이 예제에서 모든 항목의 id 열은 동일합니다. 그런 다음 수량이 5인 두 항목이 수량이 10인 항목보다 먼저 정렬됩니다. 마지막으로 가격이 1인 item이 가격이 8인 항목보다 먼저 정렬됩니다.

구조화된 데이터 정렬

셀 경로

테이블과 같은 더 복잡한 유형을 정렬하려면 sort-by 명령을 사용할 수 있습니다. sort-by는 셀 경로별로 입력을 정렬할 수 있습니다.

다음은 파일 크기별로 정렬된 예제 디렉터리입니다.

ls | sort-by size
# => ╭───┬─────────────────────┬──────┬──────────┬────────────────╮
# => │ # │        name         │ type │   size   │    modified    │
# => ├───┼─────────────────────┼──────┼──────────┼────────────────┤
# => │ 0 │ my-secret-plans.txt │ file │    100 B │ 10 minutes ago │
# => │ 1 │ shopping_list.txt   │ file │    100 B │ 2 months ago   │
# => │ 2 │ myscript.nu         │ file │  1.1 KiB │ 2 weeks ago    │
# => │ 3 │ bigfile.img         │ file │ 10.0 MiB │ 3 weeks ago    │
# => ╰───┴─────────────────────┴──────┴──────────┴────────────────╯

sort-by에 여러 셀 경로를 제공할 수도 있으며, 그러면 우선 순위 순서대로 각 셀 경로별로 정렬됩니다. 여러 셀 경로를 제공하는 것을 값이 같은 요소에 대한 "동점자"로 생각할 수 있습니다. 먼저 크기별로 정렬한 다음 수정 시간별로 정렬해 보겠습니다.

ls | sort-by size modified
# => ╭───┬─────────────────────┬──────┬──────────┬────────────────╮
# => │ # │        name         │ type │   size   │    modified    │
# => ├───┼─────────────────────┼──────┼──────────┼────────────────┤
# => │ 0 │ shopping_list.txt   │ file │    100 B │ 2 months ago   │
# => │ 1 │ my-secret-plans.txt │ file │    100 B │ 10 minutes ago │
# => │ 2 │ myscript.nu         │ file │  1.1 KiB │ 2 weeks ago    │
# => │ 3 │ bigfile.img         │ file │ 10.0 MiB │ 3 weeks ago    │
# => ╰───┴─────────────────────┴──────┴──────────┴────────────────╯

이번에는 shopping_list.txt가 my-secret-plans.txt보다 수정 시간이 더 빠르기 때문에 먼저 나오고, 두 개의 더 큰 파일은 .txt 파일 뒤에 정렬된 상태로 유지됩니다.

또한 더 복잡한 셀 경로를 사용하여 중첩된 데이터를 정렬할 수 있습니다.

let cities = [
    {name: 'New York', info: { established: 1624, population: 18_819_000 } }
    {name: 'Kyoto', info: { established: 794, population: 37_468_000 } }
    {name: 'São Paulo', info: { established: 1554, population: 21_650_000 } }
]
$cities | sort-by info.established
# => ╭───┬───────────┬────────────────────────────╮
# => │ # │   name    │            info            │
# => ├───┼───────────┼────────────────────────────┤
# => │ 0 │ Kyoto     │ ╭─────────────┬──────────╮ │
# => │   │           │ │ established │ 794      │ │
# => │   │           │ │ population  │ 37468000 │ │
# => │   │           │ ╰─────────────┴──────────╯ │
# => │ 1 │ São Paulo │ ╭─────────────┬──────────╮ │
# => │   │           │ │ established │ 1554     │ │
# => │   │           │ │ population  │ 21650000 │ │
# => │   │           │ ╰─────────────┴──────────╯ │
# => │ 2 │ New York  │ ╭─────────────┬──────────╮ │
# => │   │           │ │ established │ 1624     │ │
# => │   │           │ │ population  │ 18819000 │ │
# => │   │           │ ╰─────────────┴──────────╯ │
# => ╰───┴───────────┴────────────────────────────╯

키 클로저로 정렬

때로는 "증가" 또는 "감소"보다 더 복잡한 방식으로 데이터를 정렬하는 것이 유용합니다. 셀 경로와 함께 sort-by를 사용하는 대신 클로저를 제공할 수 있으며, 이는 기본 데이터를 변경하지 않고 각 값을 정렬 키로 변환합니다. 다음은 평균 성적별로 과제 목록을 정렬하려는 키 클로저의 예입니다.

let assignments = [
    {name: 'Homework 1', grades: [97 89 86 92 89] }
    {name: 'Homework 2', grades: [91 100 60 82 91] }
    {name: 'Exam 1', grades: [78 88 78 53 90] }
    {name: 'Project', grades: [92 81 82 84 83] }
]
$assignments | sort-by { get grades | math avg }
# => ╭───┬────────────┬───────────────────────╮
# => │ # │    name    │        grades         │
# => ├───┼────────────┼───────────────────────┤
# => │ 0 │ Exam 1     │ [78, 88, 78, 53, 90]  │
# => │ 1 │ Project    │ [92, 81, 82, 84, 83]  │
# => │ 2 │ Homework 2 │ [91, 100, 60, 82, 91] │
# => │ 3 │ Homework 1 │ [97, 89, 86, 92, 89]  │
# => ╰───┴────────────┴───────────────────────╯

값은 키 클로저의 파이프라인 입력으로 전달되지만 매개변수로 사용할 수도 있습니다.

let weight = {alpha: 10, beta: 5, gamma: 3}
[alpha gamma beta gamma alpha] | sort-by {|val| $weight | get $val }
# => ╭───┬───────╮
# => │ 0 │ gamma │
# => │ 1 │ gamma │
# => │ 2 │ beta  │
# => │ 3 │ alpha │
# => │ 4 │ alpha │
# => ╰───┴───────╯

사용자 지정 정렬 순서

키 클로저 외에도 sort-by는 사용자 지정 정렬 순서를 지정하는 클로저도 지원합니다. --custom 또는 -c 플래그는 sort-by에게 클로저를 사용자 지정 정렬 클로저로 해석하도록 지시합니다. 사용자 지정 정렬 클로저에는 두 개의 매개변수가 있으며 부울을 반환합니다. 클로저는 첫 번째 매개변수가 정렬 순서에서 두 번째 매개변수보다 앞에 오면 true를 반환해야 합니다.

간단한 예로, 셀 경로 정렬을 사용자 지정 정렬로 다시 작성할 수 있습니다. 이것은 "$a.size가 $b.size보다 작으면 정렬 순서에서 a가 b보다 앞에 와야 합니다"라고 읽을 수 있습니다.

ls | sort-by -c {|a, b| $a.size < $b.size }
# => ╭───┬─────────────────────┬──────┬──────────┬────────────────╮
# => │ # │        name         │ type │   size   │    modified    │
# => ├───┼─────────────────────┼──────┼──────────┼────────────────┤
# => │ 0 │ my-secret-plans.txt │ file │    100 B │ 10 minutes ago │
# => │ 1 │ shopping_list.txt   │ file │    100 B │ 2 months ago   │
# => │ 2 │ myscript.nu         │ file │  1.1 KiB │ 2 weeks ago    │
# => │ 3 │ bigfile.img         │ file │ 10.0 MiB │ 3 weeks ago    │
# => ╰───┴─────────────────────┴──────┴──────────┴────────────────╯

팁

매개변수는 두 요소 목록으로 사용자 지정 클로저에 전달되므로 다음은 동일합니다.

  • {|a, b| $a < $b }
  • { $in.0 < $in.1 } :::

다음은 키 정렬로 간단하게 작성할 수 없는 사용자 지정 정렬의 예입니다. 이 예제에서는 작업 시간과 우선 순위가 있는 작업 대기열이 있습니다. 우선 순위(가장 높은 순서)별로 정렬하고 싶습니다. 작업 시간이 0인 작업이 있으면 즉시 예약하고, 그렇지 않으면 작업 시간을 무시합니다.

let queue = [
    {task: 139, work_time: 0,   priority: 1 }
    {task: 52,  work_time: 355, priority: 8 }
    {task: 948, work_time: 72,  priority: 2 }
    {task: 583, work_time: 0,   priority: 5 }
]
let my_sort = {|a, b|
    match [$a.work_time, $b.work_time] {
        [0, 0] => ($a.priority > $b.priority) # 작업 시간이 같으면 우선 순위로 대체
        [0, _] => true, # a만 작업 시간이 0이므로 정렬 순서에서 a가 b보다 앞에 옴
        [_, 0] => false, # b만 작업 시간이 0이므로 정렬 순서에서 a가 b보다 뒤에 옴
        _ => ($a.priority > $b.priority) # 둘 다 0이 아닌 작업 시간을 가지므로 우선 순위로 정렬
    }
}
$queue | sort-by -c $my_sort

특수 정렬

대소문자를 구분하지 않는 정렬

대소문자를 구분하지 않는 정렬을 사용할 때 대소문자만 다른 문자열(및 glob)은 정렬에 대해 동일한 것으로 간주되는 반면 다른 유형은 영향을 받지 않습니다.

let data = [
    Nushell,
    foobar,
    10,
    nushell,
    FoOBaR,
    9
]
$data | sort -i
# => ╭───┬─────────╮
# => │ 0 │       9 │
# => │ 1 │      10 │
# => │ 2 │ foobar  │
# => │ 3 │ FoOBaR  │
# => │ 4 │ Nushell │
# => │ 5 │ nushell │
# => ╰───┴─────────╯

자연 정렬

자연 정렬 옵션을 사용하면 숫자가 포함된 문자열을 숫자가 일반적으로 정렬되는 것과 같은 방식으로 정렬할 수 있습니다. 이것은 숫자로만 구성된 문자열과 숫자와 문자가 있는 문자열 모두에 대해 작동합니다.

let data = ["10", "9", "foo123", "foo20", "bar123", "bar20"]
$data | sort
# => ╭───┬────────╮
# => │ 0 │ 10     │
# => │ 1 │ 9      │
# => │ 2 │ bar123 │
# => │ 3 │ bar20  │
# => │ 4 │ foo123 │
# => │ 5 │ foo20  │
# => ╰───┴────────╯
# "1"은 "9"보다 먼저 정렬되므로 "10"은 "9"보다 먼저 정렬됩니다.
$data | sort -n
# => ╭───┬────────╮
# => │ 0 │ 9      │
# => │ 1 │ 10     │
# => │ 2 │ bar20  │
# => │ 3 │ bar123 │
# => │ 4 │ foo20  │
# => │ 5 │ foo123 │
# => ╰───┴────────╯

또한 자연 정렬을 사용하면 숫자와 숫자 문자열을 함께 정렬할 수 있습니다.

let data = [4, "6.2", 1, "10", 2, 8.1, "3", 5.5, "9", 7]
$data | sort -n
# => ╭───┬──────╮
# => │ 0 │    1 │
# => │ 1 │    2 │
# => │ 2 │ 3    │
# => │ 3 │    4 │
# => │ 4 │ 5.50 │
# => │ 5 │ 6.2  │
# => │ 6 │    7 │
# => │ 7 │ 8.10 │
# => │ 8 │ 9    │
# => │ 9 │ 10   │
# => ╰───┴──────╯

혼합 유형으로 정렬

어떤 상황에서는 혼합 유형이 포함된 데이터를 정렬해야 할 수 있습니다. 혼합 유형을 정렬할 때 알아야 할 몇 가지 사항이 있습니다.

  • 일반적으로 동일한 유형의 값은 정렬 순서에서 서로 옆에 표시됩니다. 예를 들어, 정렬된 숫자가 먼저 오고, 그 다음 정렬된 문자열, 그 다음 정렬된 목록이 옵니다.
  • 일부 유형은 정렬 순서에서 혼합됩니다. 다음과 같습니다.
    • 정수 및 부동 소수점. 예를 들어 [2.2, 1, 3]은 [1, 2.2, 3]으로 정렬됩니다.
    • 문자열 및 glob. 예를 들어 [("b" | into glob) a c]는 [a b c]로 정렬됩니다(여기서 b는 여전히 glob임).
    • 자연 정렬을 사용하는 경우 정수, 부동 소수점 및 문자열이 해당 섹션에 설명된 대로 혼합됩니다.
  • 혼합되지 않은 유형 간의 순서는 null 값을 제외하고 보장되지 않으며, 이는 항상 목록의 끝으로 정렬됩니다.
    • 동일한 누셸 버전 내에서 순서는 항상 동일해야 하지만 이에 의존해서는 안 됩니다. 유형 간의 순서에 민감한 코드가 있는 경우 요구 사항을 더 잘 표현하는 사용자 지정 정렬을 사용하는 것을 고려하십시오.

혼합 유형이 포함될 수 있는 데이터를 정렬해야 하는 경우 다음 전략 중 하나를 고려하십시오.

  • 엄격한 정렬을 사용하여 호환되지 않는 유형의 정렬을 허용하지 않습니다.
  • 자연 정렬을 사용하여 혼합된 숫자와 숫자 문자열을 정렬합니다.
  • to text, to nuon 또는 to json을 적절하게 사용하는 키 정렬
  • describe를 사용하여 유형을 명시적으로 확인하는 사용자 지정 정렬

엄격한 정렬

사용자 지정 정렬 클로저는 잘 정의된 비교가 있는 유형만 함께 정렬되도록 하면서 데이터를 정렬하는 간단한 방법을 제공합니다. 이것은 호환되는 데이터 유형을 요구하는 연산자를 활용합니다.

let compatible = [8 3.2 null 58 2]
let incompatible = ["hello" 4 9 2 1 "meow" 8 6]
$compatible | sort-by -c {|a, b| $a < $b | default ($a != null) }
# => ╭───┬──────╮
# => │ 0 │    2 │
# => │ 1 │ 3.20 │
# => │ 2 │    8 │
# => │ 3 │   58 │
# => │ 4 │      │
# => ╰───┴──────╯
$incompatible | sort-by -c {|a, b| $a < $b | default ($a != null) }
# => Error: nu::shell::type_mismatch
# =>
# =>   × Type mismatch during operation.
# =>    ╭─[entry #26:1:36]
# =>  1 │ $incompatible | sort-by -c {|a, b| $a < $b | default ($a != null) }
# =>    ·                                    ─┬ ┬ ─┬
# =>    ·                                     │ │  ╰── string
# =>    ·                                     │ ╰── type mismatch for operator
# =>    ·                                     ╰── int
# =>    ╰────

null 값은 모든 값과 null 간의 비교가 null을 반환하므로 특별한 처리가 필요합니다. 대신 null 값을 거부하려면 다음을 시도하십시오.

let baddata = [8 3.2 null 58 2]
let strict = {|a, b|
    match [$a, $b] {
        [null, _] => (error make {msg: "Attempt to sort null"}),
        [_, null] => (error make {msg: "Attempt to sort null"}),
        _ => ($a < $b)
    }
}
$baddata | sort-by -c $strict
# => Error:   × Attempt to sort null
# =>    ╭─[entry #3:4:21]
# =>  3 │   match [$a, $b] {
# =>  4 │       [null, _] => (error make {msg: "Attempt to sort null"}),
# =>    ·                     ─────┬────
# =>    ·                          ╰── originates from here
# =>  5 │       [_, null] => (error make {msg: "Attempt to sort null"}),
# =>    ╰────
GitHub에서 수정하기
Contributors: 132ikl, 0x4D5352, NotTheDr01ds, joshuanussbaum, Axlefublr, voyage200🍬, Taeyoon Kim, ImgBotApp, google-labs-jules[bot], deepthought
Prev
오버레이
Next
누셸 코드 테스트