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

연산자

누셸은 일반적인 수학, 논리 및 문자열 연산을 위해 다음 연산자를 지원합니다.

연산자설명
+더하기
-빼기
*곱하기
/나누기
//정수/내림 나누기
mod모듈로
**거듭제곱
==같음
!=같지 않음
<작음
<=작거나 같음
>큼
>=크거나 같음
=~ 또는 like정규식 일치 / 문자열이 다른 문자열 포함
!~ 또는 not-like역 정규식 일치 / 문자열이 다른 문자열을 포함하지 않음
in목록에 값이 있음
not-in목록에 값이 없음
has목록에 값이 있음
not-has목록에 값이 없음
not논리 부정
and두 부울 표현식의 논리곱 (단락 평가)
or두 부울 표현식의 논리합 (단락 평가)
xor두 부울 표현식의 배타적 논리합
bit-or비트 OR
bit-xor비트 XOR
bit-and비트 AND
bit-shl비트 왼쪽 시프트
bit-shr비트 오른쪽 시프트
starts-with문자열이 ~로 시작
ends-with문자열이 ~로 끝남
++목록 추가

괄호는 평가 순서를 지정하기 위해 그룹화하거나 명령을 호출하고 표현식에서 결과를 사용하는 데 사용할 수 있습니다.

연산 순서

연산의 우선 순위를 이해하려면 help operators | sort-by precedence -r 명령을 실행할 수 있습니다.

우선 순위가 높은 순서대로 나열된 이 문서에서는 연산을 다음과 같이 자세히 설명합니다.

  • 괄호 (())
  • 거듭제곱/멱 (**)
  • 곱하기 (*), 나누기 (/), 정수/내림 나누기 (//), 모듈로 (mod)
  • 더하기 (+) 및 빼기 (-)
  • 비트 시프트 (bit-shl, bit-shr)
  • 비교 연산 (==, !=, <, >, <=, >=), 멤버십 테스트 (in, not-in, starts-with, ends-with), 정규식 일치 (=~, !~), 목록 추가 (++)
  • 비트 AND (bit-and)
  • 비트 XOR (bit-xor)
  • 비트 OR (bit-or)
  • 논리 AND (and)
  • 논리 XOR (xor)
  • 논리 OR (or)
  • 할당 연산
  • 논리 NOT (not)
3 * (1 + 2)
# => 9

유형

모든 연산이 모든 데이터 유형에 대해 의미가 있는 것은 아닙니다. 호환되지 않는 데이터 유형에 대해 연산을 시도하면 무엇이 잘못되었는지 설명하는 오류 메시지가 표시됩니다.

"spam" - 1
# => Error: nu::parser::unsupported_operation (link)
# =>
# =>   × Types mismatched for operation.
# =>    ╭─[entry #49:1:1]
# =>  1 │ "spam" - 1
# =>    · ───┬── ┬ ┬
# =>    ·    │   │ ╰── int
# =>    ·    │   ╰── doesn't support these values.
# =>    ·    ╰── string
# =>    ╰────
# =>   help: Change string or int to be the right types and try again.

규칙이 때로는 약간 엄격하게 느껴질 수 있지만, 반면에 예기치 않은 부작용이 적을 것입니다.

정규식 / 문자열 포함 연산자

=~ 및 !~ 연산자는 정규식을 평가하는 편리한 방법을 제공합니다. 정규식을 몰라도 사용할 수 있습니다. 또한 한 문자열이 다른 문자열을 포함하는지 확인하는 쉬운 방법이기도 합니다.

  • string =~ pattern은 string이 pattern과 일치하는 경우 true를 반환하고 그렇지 않으면 false를 반환합니다.
  • string !~ pattern은 string이 pattern과 일치하는 경우 false를 반환하고 그렇지 않으면 true를 반환합니다.

예시:

foobarbaz =~ bar # true 반환
foobarbaz !~ bar # false 반환
ls | where name =~ ^nu # 이름이 "nu"로 시작하는 모든 파일 반환

두 연산자 모두 Rust 정규식 크레이트의 is_match() 함수를 사용합니다.

대소문자 구분

연산자는 일반적으로 문자열에 대해 작동할 때 대소문자를 구분합니다. 대신 대소문자를 구분하지 않는 작업을 수행하는 몇 가지 방법이 있습니다.

  1. 정규식 연산자에서 (?i) 대소문자 구분 안 함 모드 수정자를 지정합니다.
"FOO" =~ "foo" # false 반환
"FOO" =~ "(?i)foo" # true 반환
  1. str contains 명령의 --ignore-case 플래그를 사용합니다.
"FOO" | str contains --ignore-case "foo"
  1. 비교하기 전에 str downcase를 사용하여 문자열을 소문자로 변환합니다.
("FOO" | str downcase) == ("Foo" | str downcase)

스프레드 연산자

누셸에는 목록과 레코드를 풀기 위한 스프레드 연산자(...)가 있습니다. 이전에 자바스크립트를 사용해 본 적이 있다면 익숙할 것입니다. 일부 언어에서는 스프레드/스플랫 연산자에 *를 사용합니다. 여러 값이나 키-값 쌍이 예상되는 곳에서 목록이나 레코드를 확장할 수 있습니다.

스프레드 연산자를 사용할 수 있는 세 곳이 있습니다.

  • 목록 리터럴
  • 레코드 리터럴
  • 명령 호출

목록 리터럴에서

여러 목록을 함께 연결하고 싶지만 개별 값을 산재시키고 싶다고 가정해 보겠습니다. append 및 prepend를 사용하여 이 작업을 수행할 수 있지만 스프레드 연산자를 사용하면 더 쉽게 할 수 있습니다.

let dogs = [Spot, Teddy, Tommy]
let cats = ["Mr. Humphrey Montgomery", Kitten]
[
  ...$dogs
  Polly
  ...($cats | each { |elt| $"($elt) \(cat\)" })
  ...[Porky Bessie]
  ...Nemo
]
# => ╭───┬───────────────────────────────╮
# => │ 0 │ Spot                          │
# => │ 1 │ Teddy                         │
# => │ 2 │ Tommy                         │
# => │ 3 │ Polly                         │
# => │ 4 │ Mr. Humphrey Montgomery (cat) │
# => │ 5 │ Kitten (cat)                  │
# => │ 6 │ Porky                         │
# => │ 7 │ Bessie                        │
# => │ 8 │ ...Nemo                       │
# => ╰───┴───────────────────────────────╯

아래 코드는 append를 사용한 동일한 버전입니다.

$dogs |
  append Polly |
  append ($cats | each { |elt| $"($elt) \(cat\)" }) |
  append [Porky Bessie] |
  append ...Nemo

각 append 호출은 새 목록을 생성하므로 이 두 번째 예제에서는 불필요한 중간 목록 3개가 생성됩니다. 스프레드 연산자의 경우에는 그렇지 않으므로 많은 큰 목록을 반복해서 결합하는 경우 ...를 사용하면 (아주 약간의) 성능 이점이 있을 수 있습니다.

위 결과 목록의 마지막 항목이 "...Nemo"라는 것을 알 수 있습니다. 이는 목록 리터럴 내부에서는 문자열이 아닌 목록을 전파하는 데만 사용할 수 있기 때문입니다. 따라서 목록 리터럴 내부에서는 변수(...$foo), 하위 표현식(...(foo)) 및 목록 리터럴(...[foo]) 앞에서만 사용할 수 있습니다.

...와 다음 표현식 사이에 공백이 있으면 스프레드 연산자로 인식되지 않습니다.

[ ... [] ]
# => ╭───┬────────────────╮
# => │ 0 │ ...            │
# => │ 1 │ [list 0 items] │
# => ╰───┴────────────────╯

이는 주로 ...가 mv ... $dir와 같은 명령에서 스프레드 연산자와 혼동되지 않도록 하기 위한 것입니다.

레코드 리터럴에서

일부 구성 정보가 있는 레코드가 있고 이 레코드에 필드를 더 추가하고 싶다고 가정해 보겠습니다.

let config = { path: /tmp, limit: 5 }

스프레드 연산자를 사용하여 $config의 모든 필드와 일부 새로운 추가 사항이 있는 새 레코드를 만들 수 있습니다. 단일 레코드 리터럴 내에서 여러 레코드를 스프레드할 수 있습니다.

{
  ...$config,
  users: [alice bob],
  ...{ url: example.com },
  ...(sys mem)
}
# => ╭────────────┬───────────────╮
# => │ path       │ /tmp          │
# => │ limit      │ 5             │
# => │            │ ╭───┬───────╮ │
# => │ users      │ │ 0 │ alice │ │
# => │            │ │ 1 │ bob   │ │
# => │            │ ╰───┴───────╯ │
# => │ url        │ example.com   │
# => │ total      │ 8.3 GB        │
# => │ free       │ 2.6 GB        │
# => │ used       │ 5.7 GB        │
# => │ available  │ 2.6 GB        │
# => │ swap total │ 2.1 GB        │
# => │ swap free  │ 18.0 MB       │
# => │ swap used  │ 2.1 GB        │
# => ╰────────────┴───────────────╯

목록과 마찬가지로 레코드 리터럴 내부에서 스프레드 연산자는 변수(...$foo), 하위 표현식(...(foo)) 및 레코드 리터럴(...{foo:bar}) 앞에서만 사용할 수 있습니다. 여기에서도 스프레드 연산자로 인식되려면 ...와 다음 표현식 사이에 공백이 없어야 합니다.

명령 호출에서

나머지 매개변수가 있거나 외부 명령인 경우 명령에 인수를 전파할 수도 있습니다.

다음은 나머지 매개변수가 있는 사용자 지정 명령의 예입니다.

def foo [ --flag req opt? ...args ] { [$flag, $req, $opt, $args] | to nuon }

플래그(--flag) 하나, 필수 위치 매개변수(req) 하나, 선택적 위치 매개변수(opt?) 하나, 나머지 매개변수(args) 하나가 있습니다.

args에 전달할 인수 목록이 있는 경우 목록 리터럴 내부에서 목록을 전파하는 것과 같은 방식으로 전파할 수 있습니다. 동일한 규칙이 적용됩니다. 스프레드 연산자는 변수, 하위 표현식 및 목록 리터럴 앞에서만 인식되며 그 사이에 공백이 허용되지 않습니다.

foo "bar" "baz" ...[1 2 3] # ...를 사용하면 숫자가 별도의 인수로 처리됩니다.
# => [false, bar, baz, [1, 2, 3]]
foo "bar" "baz" [1 2 3] # ...가 없으면 [1 2 3]이 단일 인수로 처리됩니다.
# => [false, bar, baz, [[1, 2, 3]]]

스프레드 연산자를 사용하는 더 유용한 방법은 나머지 매개변수가 있는 다른 명령이 있고 해당 인수를 foo에 전달하려는 경우입니다.

def bar [ ...args ] { foo --flag "bar" "baz" ...$args }
bar 1 2 3
# => [true, bar, baz, [1, 2, 3]]

단일 호출에서 여러 목록을 전파하고 개별 인수를 산재시킬 수도 있습니다.

foo "bar" "baz" 1 ...[2 3] 4 5 ...(6..9 | take 2) last
# => [false, bar, baz, [1, 2, 3, 4, 5, 6, 7, last]]

플래그/명명된 인수는 일반 나머지 인수 뒤에 올 수 있는 것처럼 스프레드 인수 뒤에 올 수 있습니다.

foo "bar" "baz" 1 ...[2 3] --flag 4
# => [true, bar, baz, [1, 2, 3, 4]]

스프레드 인수가 선택적 위치 매개변수 앞에 오면 해당 선택적 매개변수는 생략된 것으로 처리됩니다.

foo "bar" ...[1 2] "not opt" # null은 opt에 대한 인수가 제공되지 않았음을 의미합니다.
# => [false, bar, null, [1, 2, "not opt"]]
GitHub에서 수정하기
Contributors: Taeyoon Kim, ImgBotApp, google-labs-jules[bot], deepthought
Prev
별칭
Next
변수