<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      yun@dicom

      導航

      Nushell 使用說明及總結

      介紹

      作為 Shell 語言, 我特別喜歡 Nushell 的如下幾個特點:
      • 來自 UNIX Shell 的管道, 把多個命令連接在一起
      • 函數式編程風格
         事實上, 管道操作符 (|) 也是很多函數式編程的操作符
      • 豐富的對象化的數據結構
      • 對結構化文件的處理, 比如 JSON, XML, CSV, TOML 等
      • 基于模板的字符串解析
      • 在線幫助
      • 輸出結果是彩色的, 而且是表格化的, 還自帶編號 ! 真貼心 !
      • Footprint 很小, 安裝后 < 30M (0.85 版本)
      本文內容大多數來自
      (文中簡稱 book), 但是也有很多我自己的理解.
      鑒于 book 中, 已經把 Nushell 的介紹和使用說的非常詳細了, 本文不打算重復或大批量抄錄其內容, 更多是補充和總結.
       

      基礎知識

       首先

      1. 數據類型

      關于 Nushell 的數據類型, book 中也說的很詳細了. 這里只強調和補充幾個要點:
      • 可以用 describe 命令來獲得前一個管道輸出的數據類型描述
      比如 ls | describe, 就可以知道 ls 輸出的 table 的表頭的名稱和類型, 在編寫后面的語句時, 能參考這些名字
      • 可以用 into <type> 來把前一個管道輸出的數據類型轉換成當前引用的數據類型
      • 字符串可以用單引號, 也可以用雙引號, 兩者稍有不同
      • 字符串也可以不用任何引號, 這叫裸字符串. 比引號更好的地方在于, 裸串不需要轉義
      例如:
      open d:\tmp\aa.txt
      對比: 
      open "d:\\tmp\\aa.txt"
         
      • null 是特殊的,內定的數據, 表示 "沒數據/未定義", 類似 C 中的 void, C# 中的 null, 或 Python 中的 None.
      例如下面語句中的 null
      [[meal size]; [arepa, null] ] | is-empty meal # false
         
      • 區間還可以用負數表示, 但是需要加上括號, 否則容易引起編譯器誤解. 例如下面的語句: 
      'abcd12345678' | str substring (-5..-2)  #456
      (-5..-2) 的意思是, 從倒數第五開始, 到倒數第二結束.
      也可以省略區間的結尾. 比如:
      (-3..)   意思是, 從倒數第三個位置開始取, 直到末尾. 即等于 (-3, -2, -1)
      這個設計理念應該是從 Python 借用過來的.
      負數區間在切片時非常有用
      • 用字符串的 parse 命令, 可以把一個字符串解釋成若干列. 這個 "按模式切片" 的功能, 真是日志分析的利器.

      2. 變量

      • Nu 中的變量,其實是 "常量", 一旦賦值后就不允許修改
      • 與常規編程語言類似, 變量有作用域, 子域可以使用同名變量, 不會覆蓋父域的同名變量
      • 變量支持路徑.
      比如 
      print $val.name
        

      3. 子表達式 

      • 可以通過圓括號 () 來執行一個子表達式并使用其結果.
      例如
      (ls)
      • 子表達式也支持路徑
      例如
      (ls).name
       
      • 子表達式可以簡化
      例如
      ls | where size > 10kb
       其實是簡化的子表達式. 完整的語法應該是 
      ls | where {|it| $it.size > 10k}
      上述語法也可以部分簡化成:
      ls | where $it.size > 10k

       或

      ls | where ($it.size > 10k)

       

      • 簡化后的子表達式, 路徑名必須寫在前面.
      以下語句非法: 
      ls | where 10k < size

      但以下語句合法: 
      ls | where 10k < $it.size
      ls | where (10k < $it.size)

       

      ls 命令介紹

      列出指定目錄中的目錄名/文件名, 大小, 修改時間

      完整格式

      ls {flags} (pattern) 
       

      Flags:

      --all, -a : 顯示隱藏文件
      --long, -l : 長格式, 顯示所有的列 (稍慢, 且列內容依賴于平臺)
      --short-names, -s : 僅顯示文件名, 不顯示路徑
      --full-paths, -f : 把路徑顯示成絕對路徑
      --du, -d : 在目錄尺寸列的位置, 顯示整個目錄所有文件和目錄占用的空間 (disk usage)
      --directory, -D : 顯示指定的目錄, 而不是其內容
      --mime-type, -m : 針對文件, 在類型列, 顯示其 mime 類型, 而不是 'file'.
      只根據文件名決定其 mime 類型, 不檢查文件內容
       

      參數:

      -- pattern:
       

      輸入輸出:

      輸入: 無
      輸出: table (表格)
      可以用如下語句獲得輸出類型:
      ls | describe
      上述語句輸出如下 
      table <
      name: string, // 文件名/目錄名
      type: string, // 類型 (file/dir)
      size: filesize, // 文件大小
      modified: date > // 最后一次修改日期+時間
      如果是長格式, 輸出的表格包含更多內容 (長格式依賴于平臺)
      ls -l | describe 
      上述語句輸出如下:
      table <
      name: string, // 文件名/目錄名
      type: string, // 類型 (file/dir)
      target: nothing, // ??
      readonly: bool, // 是否只讀
      size: filesize, // 文件大小
      created: date, // 創建日期+時間
      accessed: date, // 訪問日期+時間
      modified: date> // 最后一次修改日期+時間
       

      例子:

      列出指定類型的文件

      ls *.txt

      列出子目錄下的文件/目錄

      ls out 

      列出文件及目錄, 但是其名稱中不包含 bar

      ls -s | where name !~ bar 

      只列出目錄, 忽略文件類型

      ls | where type == 'dir' 

      列出最近 7 天修改過的所有文件, 并且遞歸子目錄

      ls **\*.* | where type == 'file' and modified > ((date now) - 7day)

      把目標目錄放在變量中

      let dir = "E:\\Work";
      ls $"($dir)\\**\\*.cpp"

      按大小排序, 倒序

      ls | sort-by size | reverse 

      顯示部分列 - 文件名及大小 (忽略修改時間等)

      ls | select name, size 

      把輸出重定向到一個文件

      ls | get name | save a:\aa.txt 

      注意: 重定向也要通過管道操作符, 不能用傳統 shell 的 >. 

      列出特定條件的文件, 條件由我指定

      ls | where ($it.name | str contains -i "txt") 
       

      表格 (table) 及處理

       

      Nu 提供了許多處理表格的命令. 本章總結一下.

      ls 命令的輸出就是一個表格, 因此本節的大多數示例都用 ls 命令生成表格

      排序 - sort-by

      可以用 sort-by 命令對一個表進行排序, 參數為列名.
      例如

      ls | sort-by size

       

      選取 - select

      可以從表中選擇特定的列或行來形成新的表格

      選取 - 列. select 后面帶一個或多個列名

      ls | select name size


      選取 - 行:

      first 數字: 指定選擇開始的 N 行
      skip 數字: 跳過不需要的 N 行
      select 數字: 選擇指定的一行

      例子:

      ls | sort-by size | first 5
      ls | sort-by size | skip 2

       

      從表格提取數據 - get

      參數: 列名. 返回類型: 列表

      例子:

      ls | get name

      上述 get 操作返回一個列表. 可以用如下語句確認輸出類型:

      ls | get name | describe

       返回如下:

      list <string>

       

       

      列表 (list) 及處理

       

      什么是列表 - List

      列表 (List) 是一個有序的值的集合.
      可以用方括號創建一個列表, 元素之間的間隔可以是空格或逗號.
      例如

      [1 2 3]
      [a, b, c]

       

      迭代列表 - each

      要遍歷一個列表中的元素, 可以用 each 命令與 Nu 代碼塊來指定對一個元素可以做什么操作.

      塊參數 (例如 { |it| echo $it } 中的 |it|) 通常是當前的元素.

      ls | get name | each {|it| echo $it}

       可以用 where 命令來過濾, 得到列表的子集. 例如

      let colors = [red orange yellow green blue purple]
      $colors | where ($it | str ends-with 'e')

      又如 

      let lst = [1, 3, 5, 7, 9]
      $lst | where ($it > 5)

       

      訪問單個元素

      可以用 $lst.index 來獲得指定索引的單個元素. 其中 index 是給定的索引
      例如

      let lst = [1, 3, 5, 7, 9]
      $lst.1 # 返回 3

       如果索引在某個變量中, 可以使用 get 命令從列表中提前元素. 例如

      let lst = [1, 3, 5, 7, 9]
      let index = 2
      $lst | get $index # 返回 5

       當然, 下面的代碼也是可以的, 雖然有點啰嗦

      let lst = [1, 3, 5, 7, 9]
      $lst | get 2 # 返回 5

       

      獲取元素個數 - length

      length 命令可以獲得列表中的元素個數

      let lst = [1, 3, 5, 7, 9]
      $lst | length

       當然, length 命令也可以用于獲得表格的行數

       

      判空 - is-empty

      is-empty 命令可以判定一個列表是否為空

      例如:

      let lst = [1, 3, 5, 7, 9]
      $lst | is-empty # 返回 false

       

      let lst = []
      $lst | is-empty # 返回 true

       

      又, is-empty 命令也可以用于字符串或表格

         

      字符串及處理

      字符串既可以用單引號也可以用雙引號, 但兩者的語法方面有差異
      單引號字符串不能轉義, 而雙引號字符串可以轉義.
       

      字符串插值 (String interpolation) - 用對象名稱甚至表達式來直接替換原位

      這是一種從原始文本和執行表達式的結果中構建文本的方法.
      字符串插值將這些結果結合在一起, 返回新的字符串.
      在單引號或雙引號前加入 $ 字符, 就表示字符串插值.
      原位對象用 ($name) 表示, 原位表達式用 (exp) 表示

      以下是幾個例子

      let name = "Alice"
      $"greeting, ($name)"

       輸出:

      greeting, Aliceing>

       

      $"Do you know that 2+2 is (2 + 2) ?"

       輸出:

      Do you know that 2+2 is 4 ?

       注意: 上述語句中的 (2 + 2) 中的兩個空格不可少, 否則就不是合法表達式

      字符串分割 - split row

      split row 命令從一個基于分隔符的字符串來創建一個列表.
      例如:

      let colors = "red orange yellow green blue purple"
      $colors | split row ' '

      返回:

      │ 0 │ red │
      │ 1 │ orange │
      │ 2 │ yellow │
      │ 3 │ green │
      │ 4 │ blue │
      │ 5 │ purple │

       

      split column

      從一個基于分隔符的字符串來創建一個表, 并為每個元素添加一列
      例如:

      let colors = "red orange yellow green blue purple"
      $colors | split column ' '

       返回:

      │ # │ column1 │ column2 │ column3 │ column4 │ column5 │ column6 │
      │ 0 │ red │ orange │ yellow │ green │ blue │ purple │

       

      split chars

      將一個字符串分割成一個字符列表

      split words

      將一個字符串分隔成單詞列表
      例如:

      $colors | split words

       返回:

      │ 0 │ red │
      │ 1 │ orange │
      │ 2 │ yellow │
      │ 3 │ green │
      │ 4 │ blue │
      │ 5 │ purple │

      可以用 help split 來顯示完整的命令


      str 命令

      許多字符串函數是 str 命令的子命令.

      可以用 help str 來顯示完整的命令

      str contains

      檢查字符串中是否包含某個字符或子串
      例如:

      "hello world" | str contains 'w' #返回: true
      "hello world" | str contains 'wor' #返回: true
      "hello world" | str contains 'xor' #返回: false

       

      可以忽略大小寫:

      "hello world" | str contains 'W' #返回: false
      "hello world" | str contains -i 'W' #返回: true

       

      str trim

      可以修剪字符串兩邊的空白
      例如:

      ' My string ' | str trim

       返回

      My string

      帶 -l 或 --left 參數以指定只修剪左側

      帶 -r 或 --right 參數以指定只修剪右側

       

      str substring

      截取子串

      例如:

      'Hello World!' | str substring 4..8 #o Wo
      'abcd1234' | str substring 2.. #cd1234
      'abcd1234' | str substring ..4 #abcd

      范圍中, 還可以用負數, 類似于 Python. 例如

      'abcd1234' | str substring ..-2 #abcd12
      'abcd1234' | str substring ..-3 #abcd1

      取最右邊的 3 個字符, 也類似 Python

      'abcd12345678' | str substring (-3..) #678

       上述語句中:

      • 因為首字為負數, 因此范圍必須用圓括號 (), 否則被當成 flag
      • (-3..) 意思是, 從倒數第三個位置開始取, 直到末尾. 即等于 (-3, -2, -1)
      • (-3..-1) 意思是, 從倒數第三個位置開始取, 直到倒數第一. 即等于 (-3, -2)

      str start-with / str end-with

      str start-with 命令可以判斷字符串是否以指定的子串開頭
      str end-with 命令可以判斷字符串是否以指定的子串結尾
      例如:

      "hello world" | str starts-with 'xor'
      "hello world" | str starts-with 'h'
      "hello world" | str starts-with 'he'

      "hello world" | str ends-with 'd'
      "hello world" | str ends-with 'ld'
      "hello world" | str ends-with 'orld'

       

      str index-of sub 

      str index-of sub 命令可以返回子串在長串中的位置. 例如:

      '123.456' | str index-of '1'

      如果想反向搜索-從字符串尾部開始搜索, 加上參數 -e. 例如:

      '123.4156' | str index-of '1' -e

      -e 寫前面也是可以的. 例如

      '123.4156' | str index-of -e '1'

      如果找到, 返回 0 開始的索引; 如果找不到, 返回 -1

       

      str replace

      str replace 'old' 'new' 命令可以進行子串替換
      例如:

      "hello world" | str replace 'hello' 'good'

      返回: 

      good world

       

      str upcase / str downcase : 大小寫轉換

       

      'NU' | str downcase # nu
      'nu' | str upcase # NU

       

      str length : 字符串長度

      'Hello World!' | str length #12

       

      字符串轉換

      有多種方法可以將字符串轉換為其他類型,或者反過來.

       

      轉換為字符串的若干方法:

      1. 使用 into string. 例如 123 | into string
      2. 通過字符串插值. 例如 $'(123)'
      3. 使用 build-string. 例如 build-string (123)

      字符串轉換為其他類型:

      使用 into <type>. 例如

      '123' | into int

        

      path 命令

      path 用來探索和維護文件路徑.
      使用 path 命令時, 需要帶上子命令.
      例如

      'a:\tmp\2\aa\readme.txt' | path basename

      將返回 readme.txt

       

      path 支持如下子命令

      path basename

      返回 strPath 的最后一個元素, 一般是文件名 readme.txt

      path dirname

      返回 strPath 的父目錄

      path exists

      檢查文件是否存在

      path expand

      相對路徑轉為絕對路徑

      path join

      把 list/records 轉換成 字符串

      path parse

      把 strPath 轉換成結構化的 records 類型的數據

      例如

      │ prefix │ a: │
      │ parent │ a:\tmp\2\aa │
      │ stem │ abc │
      │ extension │ txt │

       

      path relative-to

       

      path split

      把 strPath 切分成 list, 每個元素都是最小成分

      例如

      │ 0 │ a:\ │
      │ 1 │ tmp │
      │ 2 │ 2 │
      │ 3 │ aa │
      │ 4 │ abc.txt │

       

      path type

      返回路徑的類型, 比如 file, dir, symlink 等. 輸入參數 (strPath) 必須在盤上存在.

       
       

      系統命令

       

      Nushell 內置了一批系統命令, 主要有

      • 關于文件和目錄: 復制文件, 移動文件, 刪除文件, 創建目錄, 刪除目錄.

      特別提出的是, 支持修改文件時間, 監視文件變更, 搜索文件.
      搜索文件還支持兩種場景:
      1) 根據確定的文件名, 搜索文件位置和類型. 適用場景: 文件名確定, 但文件位置不確定
      2) 在指定目錄下, 按通配符搜索. 適用場景: 目錄確定, 通配符確定.

      • 目錄變更, 目錄列舉
      • 打開文件/保存文件. 特別點贊的是, 打開文件還支持 JSON/XML 等常規的結構化文件.
      • 關于進程: 列舉進程, 執行外部進程, 用默認執行器打開指定文件/打開文件夾/打開 URL
      • 注冊表查詢

       

      復制文件 - cp


      cp 命令的完整格式:
      cp {flags} (source) (destination)

      Flags:
      --recursive, -r : 遞歸子目錄
      --verbose, -v : 顯示每個處理結果
      --update, -u : 僅當 source 比 dest 新時, 或者 dest 不存在時, 才復制
      --interactive, -i : 交互式, 每個文件都問一下
      --no-symlink, -n : 忽略快捷方式或符號鏈接
      --progress, -p : 顯示進度條

      例子:
      簡單復制文件

      cp a.txt b.txt

        遞歸子目錄

      cp -r dir_a dir_b

      遞歸子目錄, 并且顯示每個處理結果

      cp -r -v dir_a dir_b

      通配符:

      cp *.txt dir_a

      僅當原文件比目標文件新時, 才復制

      cp -u a b

         

      移動文件 - mv


      mv 命令的完整格式:
      mv {flags} (source) (destination)

      Flags:
      --force, -f : 強制覆蓋目標文件
      --verbose, -v : 顯示每個處理結果
      --update, -u : 僅當 source 比 dest 新時 (此時務必 -f), 或者 dest 不存在時, 才移動
      --interactive, -i : 交互式, 每個文件都問一下

      例子:
      簡單移動文件

      mv a.txt b.txt

      移動到子目錄下

      mv a.txt dir_a\dir_b

      通配符:

      mv *.txt dir_a

      僅當原文件比目標文件新時, 才移動

      mv -u a b

        


      刪除文件 - rm


      rm 命令的完整格式:
      rm {flags} (filename) ...rest

      Flags:
      --recursive, -r : 遞歸子目錄
      --verbose, -v : 顯示每個處理結果
      --trash, -t : 移到平臺的回收站, 不是永久刪除. 對 Android 和 ios 不適用
      --permanent, -p : 永久刪除. 也忽略 'always_trash' 配置項
      --force, -f : 抑制錯誤信息 (即是文件不存在, 也不要告訴我)
      --interactive, -i : 交互式, 每個文件都問一下
      --interactive-once, -I : 交互式, 但是只問一次

      例子:
      簡單刪除文件

      rm a.txt

       移動到回收站

      rm --trash a.txt

       永久刪除

      rm -p *.txt

        強行刪除, 忽略 文件不存在 的警告

      rm -f *.txt

        刪除當前目錄中, 文件長度為 0 的所有文件

      ls | where size == 0KB and type == file | each { rm -t $in.name }

        

      創建或修改文件時間 - touch

      既能創建一個空白文件, 也能修改文件時間

      touch 命令的完整格式:
      touch {flags} (filename) ...rest

      Flags:
      --reference, -r {to} : 把所有文件的修改時間都同步成與 to 一致
      --modified, -m : 更新文件的最后修改時間. 如果未指定參數, 就把修改時間更新為當前時間
      --access, -a : 更新文件的最后訪問時間. 如果未指定參數, 就把修改時間更新為當前時間
      --no-create, -c : 如果文件不存在, 就不要創建文件了

      例子:
      簡單創建文件

      touch a.txt

       同時創建多個文件

      touch a.txt b.txt c.json

      更新文件的修改時間, 改為當前時間

      touch -m a.txt

      更新文件的修改時間, 改為昨天

      touch -m -d "yesterday" *.txt

        把文件的更新時間同步到與 test 一致

      touch -m -r test a.txt b.txt c.txt

        把文件的最后訪問時間改為指定時間

      touch -a -d "August 24, 2023; 17:12:56" a.txt b.txt c.txt

        

      搜索文件 - which

      which 用于搜索可執行文件或 DLL 的位置. 需要給定一個確切的文件名, 不能是通配符.

      貌似是在環境變量之 PATH 給出的列表中搜索

      which 命令的完整格式:
      which {flags} (filename) ...rest

      Flags:
      --all, -a : 列出所有的可執行文件

       

      例子:

      which cmd.exe

        返回:

      │ # │ command │ path │ type │
      │ 0 │ cmd.exe │ C:\WINDOWS\system32\cmd.exe │ external │

       

      which gdi32.dll

      返回:

      │ # │ command │ path │ type │
      │ 0 │ gdi32.dll │ C:\WINDOWS\system32\gdi32.dll │ external │

        


      打開目錄/文件/URL - start


      start 可以用默認的應用程序或 Viewer 來打開: 目錄, 文件, 或 URL

      start 命令的完整格式:
      start (path)

      例子:

      start a.txt
      start b.jpg

      用默認的文件管理器打開當前目錄

      start .

      用默認的瀏覽器打開 website

      start www.ibm.com

        

      執行外部命令 - run-external

      run-external 命令的完整格式:
      run-external {flags} (command) ...rest

      Flags:
      --redirect-stdout : 把 stdout 重定向到 pipeline
      --redirect-stderr : 把 stderr 重定向到 pipeline
      --redirect-combine : 把 stdout 和 stderr 都重定向到 pipeline
      --trim-end-newline : 刪除尾部的新行

      例子:

      run-external "echo" "-n" "hello"

       返回:

      -n hello

       例子:

      run-external --redirect-stdout "echo" "-n" "hello" | split chars

        返回:

      │ 0 │ - │
      │ 1 │ n │
      │ 2 │ │
      │ 3 │ h │
      │ 4 │ e │
      │ 5 │ l │
      │ 6 │ l │
      │ 7 │ o │
      │ 8 │ │
      │ 9 │ │
      │ │ │

      明顯看到, 上述返回結果中, 有空白字符

      修改命令如下, 可以刪除空白字符

      run-external --redirect-stdout --trim-end-newline "echo" "-n" "hello" | split chars

      返回:

      │ 0 │ - │
      │ 1 │ n │
      │ 2 │ │
      │ 3 │ h │
      │ 4 │ e │
      │ 5 │ l │
      │ 6 │ l │
      │ 7 │ o │

       

      文件 IO - open/save

       

      打開文件 - open

      這個操作很神奇, 能根據擴展名判斷文件類型, 然后把文件內容解釋為表格 (table),隨后就可以用命令來操縱表格啦

      擴展名最好是小寫.
      如果無法自動判斷, 可以用 from 命令作為管道來強行指定類型
      如果編碼不正確, 可以用 decode 命令作為管道.

      如何處理結果? - Filter
      打開文件之后, 返回的結果, 要么是半結構化的, 要么是全結構化的. 這時就需要用 filter 命令來處理結果. 參見章節: 常用的 filter 命令


      open 命令的完整格式:
      open {flags} (filename) ...rest

      Flags:
      --raw, -r: 作為原始格式打開

      關于 from 命令支持的文件格式, 參見章節: from 命令

       

      例子:
      打開文本文件

      open aa.txt

       打開 json 文件

      open aa.json

       打開文件, 并強行作為 json 來解釋

      open aa.json | from json

       打開文件, 并指定編碼:

      open aa.txt -- raw | decode utf-8
      open aa.txt -- raw | decode GB18030

       可以用如下命令來查看結果的格式

      open package.json | describe

       結果為 (刪除了一部分, 否則實在太長, 分行是我手工加的):

      record <
      name: string, publisher: string, description: string, displayName: string,
      engines: record <vscode: string>,
      categories: list <string>,
      activationEvents: list <string>,
      capabilities: record <virtualWorkspaces: bool, untrustedWorkspaces: record <supported: bool>>,
      contributes: record <configuration: record <...>>,
      taskDefinitions: table <
      type: string,
      required: list <string>,
      properties: record <...>
      when: string>
      >,
      repository: record <type: string, url: string>
      >

       

      結構非常復雜...


      from 命令


      把字符串或 BIN 數據解釋成結構化的數據

      目前支持以下子命令
      Subcommands:
      from csv - 解釋為 .csv, 然后創建 table.
      from json - 解釋為 json, 然后轉化為結構化數據
      from nuon - 解釋為 nuon, 然后轉化為結構化數據
      from ods - 解釋為 OpenDocument 的數據表 (.ods), 然后創建 table.
      from ssv - 解釋為空白分隔的數據, 然后創建 table. 默認的空白間隔是 2
      from toml - 解釋為 tomo, 然后創建 record
      from tsv - 解釋為 tsv, 然后創建 table.
      from xlsx - 解釋為 Excel (.xlsx), 然后創建 table
      from xml - 解釋為 xml, 然后創建 record.
      from yaml - 解釋為 yaml, 然后創建 table
      from yml - 同 yaml

       

      保存文件 - save

      save 命令的完整格式:
      save {flags} (filename)

      Flags:
      --raw, -r : 作為原始格式保存
      --append, -a : 把結果添加到文件結尾
      --force, -f : 覆蓋目標文件
      --progress, -p : 限制進度條
      --stderr, -e {path} : 把錯誤輸出重定向到 path 指定的文件中

      例子:
      把字符串保存到文件中

      "save me" | save aa.txt

      把字符串添加到文件中

      "append me" | save --append aa.txt

       把 list 保存到文件中

      [a b c d x y] | save aa.json

       運行程序, 并且把 stderr 保存到文件中 (這兩個語句沒弄懂差別在哪)

      do -i {} | save foo.txt --stderr foo.txt
      do -i {} | save foo.txt --stderr bar.txt

       save 文件前, 也許希望把數據轉換成指定的格式. 可以用下面的 to 命令 (與 from 相反)


      to 命令

      把結構化的數據轉換成指定格式
      子命令與 from 中的子命令相同
      例子:

      ls | to json | save "aa.txt"

        

      常用的 Filter 命令

       

      1. each for filters


      each 的輸入參數為 list 或 table 的每一行,
      用這個參數來運行隨后的閉包,
      運行完畢后, 所有結果再形成一個新的 list
      完整格式:
      each {flags} (closure)

      Flags:
      --keep-empty, -k : 保留空白結果

       

      例子:

      [1 2 3] | each {|e| 2 * $e }

      輸出:

      │ 0 │ 2 │
      │ 1 │ 4 │
      │ 2 │ 6 │

       

      掃描輸入的 list, 如果發現 2, 就在輸出的 list 中返回 found (否則就啥都不做):

      [1 2 3 2 1] | each {|it| if $it == 2 { "found"}}

      輸出:

      │ 0 │ found │
      │ 1 │ found │

       

      上述命令, 如果用 -k 參數:

      [1 2 3 2 1] | each-k {|it| if $it == 2 { "found"}}

      結果如下:

      │ 0 │ │
      │ 1 │ found │
      │ 2 │ │
      │ 3 │ found │
      │ 4 │ │

       

      以下例子引用了索引值 (參見 enumerate for filters)

      [1 2 3 2 1] | enumerate | each {|e| if $e.item == 2 { $"found 2 at ($e.index)!"} }

      輸出:

      │ 0 │ found 2 at 1! │
      │ 1 │ found 2 at 3! │

       

      列出目錄中的文件名, 并且把文件名存入另一個文件中

      ls | each {|e| $e.name} | save -f a:\aa.txt

       

      注意:
      因為 table 是由 record 組成的 list, 因此, 如果對一個 table 調用 each,
      那么傳遞給閉包的參數將是一個 record, 而不是一個 cell.

      另外, 也要避免將一個 record 傳遞給 each. 因為一個 record 只有一行.
      如果將 record 傳遞給 each, each 將只運行一次, 而不是把記錄中的每個元素運行一次 !
      如果非要迭代 record, 可以先把 record 轉換成 table, 再迭代這個 table. 例如

      {name: sam, rank: 10} | transpose key value

      返回如下 table: 

      │ # │ key │ value │
      │ 0 │ name │ sam │
      │ 1 │ rank │ 10 │

       

      2. enumerate for filters


      某些情況下, 我們希望迭代時, 除了值以外, 還能獲得索引. enumerate 可以滿足這種要求.
      對一個 list 執行 enumerate, 可以返回一個 table, 其中 index 是索引, item 是值

      [1 2 3 2 1] | enumerate | describe

      返回:

      table <index: int, item: int>

       

      3. where for filters


      可以用于 list, table, range
      用于 list 時, 返回 list
      用于 table 時, 返回 table
      用于 range 時, 返回 list

       

      例子:

      1..5 | where {|x| $x > 2} 

      返回

      │ 0 │ 3 │
      │ 1 │ 4 │
      │ 2 │ 5 │

       

      [1, 2, 3, 4, 5] | where {|x| $x > 2}

      也返回

      │ 0 │ 3 │
      │ 1 │ 4 │
      │ 2 │ 5 │

       

      4. length for filters


      返回 list 或 table 的數量.

      例子:

      [a b c d] | length # 4

       

      注意:
      length 不適用于字符串, 如果希望獲得字符串的長度, 請用 str length

       

      5. select for filters


      選擇指定的列.
      既可以用于 record, 也可以用于 table, 還可以用于 list
      參數可以是列名, 也可以是數字

       

      例如:

      ls | select name
      ls | select 0 1 2 3 # 選擇開始的 4 行, 等效于 ls | first 4

       

      與 get 不同的是, 用于 table 時, 返回還是 table, 用于 list 時, 返回還是 list
      例如, 比較如下兩行

      [a b c d] | select 1 # [b]
      [a b c d] | get 1 # b

       

      前者返回一個 list, 但只有一個元素: [b]. 后者直接返回值

      如果超過 1 個, 兩者返回相同的類型

      [a b c d] | select 1 2 # [b c]
      [a b c d] | get 1 2 # [b c]

       

      6. get for filters

      抽取數據
      既可以用于 record, 也可以用于 table, 還可以用于 list

       

      例子:

      ls | get name # 返回 list <name>
      ls | get 2.name # 返回 string
      ls | get name.2 # 返回 string, 與上相同
      ls | get name | get 2 # 返回 string, 與上相同
      ls | get 2 | get name # 返回 string, 與上相同

       

      get 語法還可以縮寫為如下形式, 相當于用索引訪問 list

      [a b c].2 # c

       


      7. items for filters


      給定一個 record, 迭代每個 (key, value)

      完整的語法為:
      items (closure)

       

      例子:

      ls | get 2 | items {|key, value| echo $'($key) = ($value)' }

      返回:

      name = DB.txt
      type = file
      size = 40 B
      modified = Mon, 16 Oct 2023 12:15:34 +0800 (a day ago)

       

      8. lines for filters


      把輸入轉換為 list <string>. 以換行作為分隔符.
      對 open 打開的 raw text file 特別有用, 把長串轉換為短串 list

      完整語法為:
      lines {flags}

      Flags:
      --skip-empty, -s : 跳過空行

       

      例子:

      "two\n\nlines" | lines

      返回

      │ 0 │ two │
      │ 1 │ │
      │ 2 │ lines │

        

      "two\nlines" | lines

       返回:

      │ 0 │ two │
      │ 1 │ lines │

       

      "two\n\nlines" | lines -s

      返回:

      │ 0 │ two │
      │ 1 │ lines │

       

      9. values for filters

      給定一個 record 或 table, 用 values 過濾器可以生成一個 list, 每個元素來自于指定的列值

       

      例子:

      ls | get 2 | values

      返回

      │ 0 │ DB.txt │
      │ 1 │ file │
      │ 2 │ 40 B │
      │ 3 │ a day ago │

       

      如果輸入是一個 table, 將生成 list <list <...>>.
      例如:

      ls | values

       

      注:
      與此對應的是 columns, 用 columns 過濾器可以生成一個 list, 每個元素來自于指定的列名

       

      10. columns for filters

      給定一個 record 或 table, 用 columns 過濾器可以生成一個 list, 每個元素來自于指定的列名

       

      例子:

      ls | get 2 | values

      輸出:

      │ 0 │ name │
      │ 1 │ type │
      │ 2 │ size │
      │ 3 │ modified │

       

      11. 對 list 或 table 的 "掐頭去尾"


      skip : 忽略開頭的 N 行, 如果無參數, 默認跳過開頭的第一行
      drop : 忽略結尾的 N 行, 如果無參數, 默認跳過結尾的最后一行
      first: 返回開頭的 N 行, 如果無參數, 默認返回第一行
      last : 返回結尾的 N 行, 如果無參數, 默認返回最后一行

      輸出與輸入相同: 對 list 返回 list, 對 table 返回 table

       

      例子:

       

      ls | first
      ls | last 3
      ls | skip
      ls | drop 6

       

      [a b c d ] | drop 2

      返回:

      │ 0 │ a │
      │ 1 │ b │

       

      12. 對 list 或 table, 用區間指定選擇范圍


      除了掐頭去尾以外, 有時我們還希望用一個區間來指定選擇范圍. 可以用 range 過濾器來達成這個目的

       

      例子:

      [a b c d e f] | range 2..4

      返回

      │ 0 │ c │
      │ 1 │ d │
      │ 2 │ e │

       

      返回最后兩項:

      [a b c d e f] | range (-2..)

      返回

      │ 0 │ e │
      │ 1 │ f │

       

      返回倒數第3-倒數第2:

      [a b c d e f] | range (-3..-2)

      返回:

      │ 0 │ d │
      │ 1 │ e │

       

      13. uniq for filters - 返回值去重


      完整的格式:
      uniq {flags}

      Flags:
      --count, -c: 返回 table, 其中 value 列給出去重后的值, count 列給出重復次數
      --repeated, -d: 僅返回重復出現的項 (即 count > 1 的項), 與 -u 相反
      --unique, -u: 僅返回出現一次的項 (即 count = 1 的項), 與 -d 相反
      --ignore-case, -i: 忽略大小寫

       

      例子:

      [a b a x b w c x] | uniq

      返回:

      │ 0 │ a │
      │ 1 │ b │
      │ 2 │ x │
      │ 3 │ w │
      │ 4 │ c │

       

      [a b a x b w c x] | uniq -c

      返回:

      │ # │ value │ count │
      │ 0 │ a │ 2 │
      │ 1 │ b │ 2 │
      │ 2 │ x │ 2 │
      │ 3 │ w │ 1 │
      │ 4 │ c │ 1 │

        

      [a b a x b w c x] | uniq -d

      返回:

      │ 0 │ a │
      │ 1 │ b │
      │ 2 │ x │

       

      [a b a x b w c x] | uniq -u

       返回:

      │ 0 │ w │
      │ 1 │ c │

       

      14. uniq-by for filters - 返回值去重


      如果輸入是 table, 我們希望可以按列名來去重, 這時可以用 uniq-by 過濾器. 參數中可以指定一個或多個列
      完整格式:
      uniq-by {flags} ...rest

      Flags 與 uniq 相同:

       

      例子:

       

      按 fruit 去重

      [[fruit count]; [apple 9] [apple 2] [pear 3] [orange 2]] | uniq-by fruit

      返回:

      │ # │ fruit │ count │
      │ 0 │ apple │ 9 │
      │ 1 │ pear │ 3 │
      │ 2 │ orange │ 2 │

       

      按 count 去重

      [[fruit count]; [apple 9] [apple 2] [pear 3] [orange 2]] | uniq-by count

      返回:

      │ # │ fruit │ count │
      │ 0 │ apple │ 9 │
      │ 1 │ apple │ 2 │
      │ 2 │ pear │ 3 │

       

      15. sort for filters


      排序.
      適用于 list 或 record

      完整格式:
      sort {flags}

      Flags:
      --reverse, -r: 逆序
      --ignore-case, -i: 忽略大小寫
      --values, -v: 如果輸入是單個 record, 將按其 value 排序; 否則忽略此選項
      --natural, -n: 如果輸入項是字符串組成的數字, 將轉成數字來排序

       

      例子:

      [2 0 1] | sort

      返回:

      │ 0 │ 0 │
      │ 1 │ 1 │
      │ 2 │ 2 │

       忽略大小寫排序

      [airplane Truck Car] | sort -i

       返回:

      │ 0 │ airplane │
      │ 1 │ Car │
      │ 2 │ Truck │

      record 排序, 按名稱

      {b: 4, a: 3, c:1} | sort

       返回:

      │ a │ 3 │
      │ b │ 4 │
      │ c │ 1 │

       

      record 排序, 按值

      {b: 4, a: 3, c:1} | sort -v

      返回:

      │ c │ 1 │
      │ a │ 3 │
      │ b │ 4 │

      按字母順序排序

      ["4", "300", "100"] | sort

      返回:

      │ 0 │ 100 │
      │ 1 │ 300 │
      │ 2 │ 4 │

       改成按數字順序排序:

      ["4", "300", "100"] | sort -n

       返回:

      │ 0 │ 4 │
      │ 1 │ 100 │
      │ 2 │ 300 │

       

      16. sort-by for filters


      排序.
      適用于 table

      完整格式:
      sort-by {flags} ...rest

      Flags:
      --reverse, -r: 逆序
      --ignore-case, -i: 忽略大小寫
      --natural, -n: 如果輸入項是字符串組成的數字, 將轉成數字來排序

       

      例子

      ls | sort-by modified

       

      [[fruit count]; [apple 9] [apple 2] [pear 3] [orange 2]] | sort-by fruit

      返回:

      │ # │ fruit │ count │
      │ 0 │ apple │ 9 │
      │ 1 │ apple │ 2 │
      │ 2 │ orange │ 2 │
      │ 3 │ pear │ 3 │

        

      [[fruit count]; [apple 9] [apple 2] [pear 3] [orange 2]] | sort-by count

       返回:

      │ # │ fruit │ count │
      │ 0 │ apple │ 2 │
      │ 1 │ orange │ 2 │
      │ 2 │ pear │ 3 │
      │ 3 │ apple │ 9 │

       

      17. find for filters

      搜索


      完整格式:
      find {flags} ...rest

      Flags:
      --regex, -r {string}: 用正則表達式來匹配
      --ignore-case, -i: 忽略大小寫的正則; 等效于 (?i)
      --multiline, -m: 多行正則模式: 用 ^ and $ 來匹配行初/行尾; 等效于 (?m)
      --dotall, -s: dotall 正則模式; 等效于 (?s)
      --columns, -c {list<string>}: 指定用哪些列名來搜索, 不支持正則
      --invert, -v: 反向匹配

       

      例子:
      字符串中搜索

      "abcdef" | find b

      返回:

      abcdef

      在 file size 的 list 中搜索

      [1 5 3kb 4 3Mb] | find 5 3kb

      返回:

      │ 0 │ 5 │
      │ 1 │ 2.9 KiB │

       用正則來搜索

      [abc bde arc abf] | find --regex "ab"

      返回:

      │ 0 │ abc │
      │ 1 │ abf │

       用列名來搜索

      ls | find -c [name] age

      返回:

      │ # │ name │ type │ size │ modified │
      │ 0 │ package.json │ file │ 1.9 KB │ a day ago │

       

      18. is-empty for filters


      用來判斷某個項是否為空.
      輸入參數可以是: 字符串, list, table
      完整格式:
      is-empty ...rest

      參數可以輸入列名, 用于判斷特定的某一列

       

      例子:

      ls | is-empty

       

      [[meal size]; [arepa, null] ] | is-empty meal # false
      [[meal size]; [arepa, null] ] | is-empty size # true

       

       

      系統或平臺相關的命令

       

      1. sleep - 等待/延遲


      完整格式:
      sleep (duration) ...rest

       

      例子:

      sleep 1sec # 延遲 1秒
      sleep 3sec 5min # 延遲 5分 + 3秒

       

      2. ps - 顯示進程信息


      完整格式:
      ps {flags}

      Flags:
      --long, -l: 顯示盡可能多的列

      如果不加選項, ps 輸出如下 table

      table <pid: int, ppid: int, name: string, cpu: float, mem: filesize, virtual: filesize>

       

      如果加上選項 -l, ps 輸出如下 table:

      table <pid: int, ppid: int, name: string, cpu: float, mem: filesize, virtual: filesize,
      command: string, start_time: date, user: string, user_sid: string, priority: int,
      cwd: string, environment: list<string>>

       針對 Windows 平臺:

      • mem : 對應了任務管理器中的 WorkingSet
      • command : App 的完整名稱: FullPath + App Name
      • user : 用戶名
      • user_sid : 用戶的 GUID
      • cwd : 此文件所在的目錄
      • environment : 運行環境


      例子:
      顯示占用內存最多的最后 5 個

      ps | sort-by mem | last 5

      可能的輸出:

      │ # │ pid │ ppid │ name │ cpu │ mem │ virtual │
      │ 0 │ 17896 │ 17312 │ chrome.exe │ 0.00 │ 244.7 MB │ 154.3 MB │
      │ 1 │ 17240 │ 3000 │ msedge.exe │ 0.00 │ 276.4 MB │ 166.9 MB │
      │ 2 │ 15840 │ 3000 │ WXWork.exe │ 0.00 │ 376.7 MB │ 396.5 MB │
      │ 3 │ 14132 │ 3000 │ WeChat.exe │ 0.00 │ 430.8 MB │ 363.7 MB │
      │ 4 │ 3000 │ 5536 │ Explorer.EXE │ 0.00 │ 513.0 MB │ 1.7 GB │

       

      3. kill - 殺死指定的進程


      完整格式
      kill {flags} pid ...rest

      Flags:
      --force, -f: 強行殺死
      --quiet, -q: 安靜! 不要在 Console 上顯示任何信息

      kill 通常與 ps 一起使用, 以便根據 name 獲得 pid

       

      例子:

      殺死占用內存最多的進程:

      ps | sort-by mem | last | kill $in.pid

       

       殺死含有指定名稱的所有進程:

      ps | where ($it.name | str contains -i "code.exe") | get pid | each {|it| kill -f $it }

      上述語句中, where 后面的圓括號不能省略

       
       

      核心命令

       

      1. 用 let 定義變量


      在 nu 中, 可以用 let 來定義一個 '變量'. 但其實是定義了一個常量, 一旦賦值就不能修改.
      但是可以重新定義.
      創建常量后, 可以通過 $來引用

      以下語句是合法的

      let x = 0; echo $x; let x = 'hello'; echo $x

       

      另外, 變量是有作用域的, 在嵌套塊中, 可以定義同名的變量, 這個變量不會影響上層的同名變量.
      例如:

      let my_value = 4
      do { let my_value = 5; echo $my_value }
      echo $my_value

      先輸出 5, 然后輸出 4

       

      后續語句不能修改的變量, 不能用于循環控制. 因此, 我們需要一個常規編程語言意義上的變量.
      這種情況下, 就要用 mut 來定義真正意義上的變量

       

      2. 用 mut 定義變量

      例如:

      mut a = 1; $a = $a + 10; echo $a

      將輸出 11

      有了真正的 '變量' 之后, 就可以開始探索循環了

       

      3. for 循環


      for 的完整格式:
      for {flags} (var_name) (range) (block)

      Flags:
      --numered, -n : 同時返回索引和值 ($it.index 和 $it.item)

      參數:
      var_name : 循環變量名
      range : 循環的范圍
      block : 要運行的語句塊

       

      例子:

      for x in [1 2 3] { print $x * $x}
      for $x in 1..4 { print $x}

      上述兩個語句, 循環變量用 x 和 $x 都可以

       

      舉一個同時引用索引和值的例子:

      for -n $it in ['a' 'b' 'c' 'd'] { print $"[($it.index)] is ($it.item)" }

       輸出:

      [0] is a
      [1] is b
      [2] is c
      [3] is d

       

      之前的 ls 語句還可以寫成這樣:

      for it in (ls | get name) { print $it }

      或者寫成這樣, 更簡短易懂

      for it in (ls).name { print $it }


      4. loop 循環


      loop 的完整格式:
      loop (block)

      參數:
      block : 要運行的語句塊

      loop 的語法特別簡單(粗暴): 參數只有一個語句塊.
      通常情況下, 需要配合 mut 定義的變量來控制循環何時結束

       

      例子:

      mut x = 0; loop { if $x > 10 { break }; $x = $x + 1 }; $x

       

      5. while 循環


      while 的完整格式:
      while (cond) (block)

      參數:
      cond : 要檢測的條件
      block : 要運行的語句塊

      通常情況下, 需要配合 mut 定義的變量來控制循環何時結束


      例子:

      mut x = 0; while $x < 10 { $x = $x + 1; print $"running on ($x)" }

       


      6. do 語句


      do 語句用于執行一個閉包, 自動把管道輸入 ($in) 作為參數傳入

      完整語法為:
      do {flags} (closure) ...rest

      Flags:
      --ignore-errors, -i: 閉包運行時, 忽略其錯誤
      --ignore-shell-errors, -s: 閉包運行時, 忽略 shell 錯誤
      --ignore-program-errors, -p: 閉包運行時, 忽略外部程序錯誤
      --capture-errors, -c: 閉包運行時, 捕獲錯誤, 并且返回錯誤

      參數:
      closure : 要運行的閉包
      ...rest : 給閉包的參數

       

      例子:


      運行閉包:

      do { echo hello }

       

      把閉包保存為變量, 然后運行閉包: 

      let text = "I am enclosed"; let hello = {|| echo $ text}; do $hello

       

      帶參數的閉包:

      do {|x| 100 + $x } 77

       

      從輸入管道中獲取數據

      77 | do {|| 100 + $in }

      上述語句中, $in 是系統自動傳入的管道

       
       

      幾個綜合應用的例子

       

      1. 列出目錄下的所有文件, 遞歸子目錄

      如果文件名中包含 hello, 就把這些文件復制到另一個目錄下, 同時顯示這些文件名

      ls -f **/*.* | where ($it.name | str contains -i "txt") | get name | each {|it| cp -v $it "a:\\tmp25"}

       

      如果希望把滿足條件的文件名保存起來, 可以利用 each 的特征: 把結果合成一個 list

      ls -f **/*.* | where ($it.name | str contains -i "txt") | get name | each {|it| cp -v $it "a:\\tmp25"; $it} | save -f "a:\\tmp25\\out.txt"

       

      寫成如下語句也可以:

      ls -f **/*.* | get name | each {|it| if ($it | str contains -i "txt") {$it}} | each {|it| cp -v $it "a:\\tmp25"; $it} | save -f "a:\\tmp25\\out.txt"

      或者

      ls -f **/*.* | get name | where (str contains -i "txt") | each {|it| cp -v $it "a:\\tmp25"; $it} | save -f "a:\\tmp25\\out.txt"

       

      2. 中的情形, 把不滿足條件的文件作為列表, 存為另一個文件


      ls -f **/*.* | where not ($it.name | str contains -i "txt") | get name | save -f "a:\\tmp25\\not.txt"

       

      3. 搜索一系列文件, 對每個文件進行模式匹配

      軟件開發過程和產品生命周期中, 以下場景不可避免:

      • 功能逐漸增加
      • 需求不斷變更
      • 越來越多的客戶化和定制

      隨著代碼和工程項目的分支越來越多, 版本也就越來越多, "這個功能我做過了,但是,代碼到底在哪個該死的版本中?", 這個問題經常問.

      我們可以用 Nu 來編寫腳本, 根據蛛絲馬跡, 從浩如煙海的源文件中, 找到文件名和修改時間.

       

      3.1 首先設計一個從文件中搜索字符串的自定義函數

      book 中叫自定義命令, 我更喜歡按傳統編程語言思路, 叫做函數.

       1 def on-file [filename: string subString: string] {
       2     #print $"processing ($filename)" 
       3     let ln = open $filename -r | decode GB18030 | lines;
       4     for -n $it in ($ln) {
       5         if ($it.item | str contains -i $subString) {
       6             print $"Found at line ($it.index) of file ($filename)";
       7             return true 
       8         }
       9     };
      10     return false;
      11 }

       輸入參數是兩個: 文件名和待匹配的字符串

      行 3: 定義一個變量, 保存打開文件后的行列表

      行 4: 用 for 迭代, flag 為 -n, 以便獲得迭代索引

      行 5,6,7: 如果字符串匹配成功, 就顯示行位置和文件名,然后提前返回


      以下是單元測試代碼: 

      on-file "d:\\works\\main.cpp" "RemoveFile"

       返回:

      Found at line 13 of file main.cpp

       

      3.2 在 ls 命令中, 把上述輔助函數掛到管道 | 中, 就可以搜索整個目錄了.

      代碼如下:

      ls **\*.cpp | get name | each {|it| if (on-file $it "RemoveTempFile") {$it} }

       在我機器上的運行結果如下:

      Found at line 131 of file Works.51\MainWindow.InitExit.cpp
      │ 0 │ Works.51\MainWindow.InitExit.cpp │
      Found at line 63 of file Works.51\Tool\Utility.TempFile.cpp
      Found at line 245 of file Works.51\Test\TestFrameWnd.Show.cpp
      │ 1 │ Works.51\Tool\Utility.TempFile.cpp │
      │ 2 │ Works.51\TestFrameWnd.Show.cpp │
      Found at line 149 of file Works.51\Test.InitExit.cpp
      │ 3 │ Works.51\Test.InitExit.cpp │

       print 的結果與最終 list 混合在一起了, 因為 3.2 代碼里面, each 每次迭代都執行一遍 print, 之后把管道輸出的 list 的變更也輸出

       

      3.3 換一個思路, 把 on-file 改成從管道獲得文件名

       

       1 def on-file [subString: string] {
       2     let filename = $in;
       3     #print $"processing ($filename)"
       4     let lines = open $filename -r | decode GB18030 | lines;
       5     for -n $it in ($lines) {
       6         if ($it.item | str contains -i $subString) {
       7             print $"Found at line ($it.index) of file ($filename)";
       8             return true 
       9         }
      10     };
      11     return false;
      12 }

       

      現在, 輸入參數只有一個了, 就是待匹配的子串. 而文件名來自管道輸入

      行 2, 把管道輸入保留在 filename 變量中.

      因為有兩個地方要引用文件名 (如果包括注釋就是三個引用).

      函數中如果多個地方引用 $in, 所有后續的引用, 要么為 null, 要么發生代碼解釋錯誤

      單元測試代碼需要改成:

      "d:\\works\\main.cpp" | on-file "RemoveFile"

       

      3.4 ls 命令改成:

      ls **\*.cpp | where ($it.name | on-file "RemoveTempFile") | select name

       在我機器上的運行結果如下:

      Found at line 131 of file Works.51\MainWindow.InitExit.cpp
      Found at line 63 of file Works.51\Tool\Utility.TempFile.cpp
      Found at line 245 of file Works.51\Test\TestFrameWnd.Show.cpp
      Found at line 149 of file Works.51\Test.InitExit.cpp
      │ # │ name |
      │ 0 │ Works.51\MainWindow.InitExit.cpp │
      │ 1 │ Works.51\Tool\Utility.TempFile.cpp │
      │ 2 │ Works.51\TestFrameWnd.Show.cpp │
      │ 3 │ Works.51\Test.InitExit.cpp │

      可以看到, 最終的輸出結果是一個 table. 而且不會跟 print 結果混合了.

       

      總結

       
      2023-10-20
       

      posted on 2023-10-18 20:03  yun@dicom  閱讀(2951)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 亚洲精品国产免费av| 免费无码一区无码东京热| 国产萌白酱喷水视频在线观看| 茄子视频国产在线观看| 波多野结衣av无码| 国产日韩一区二区在线看| 做暖暖视频在线看片免费| 昔阳县| 久青草精品视频在线观看| 国产亚洲精品一区二区无| 中文字幕av一区二区三区人妻少妇| 精品一区二区三区不卡| 亚洲精品一区二区三天美| 亚洲欧美中文日韩V在线观看| 最近中文字幕国产精品| 波多野结衣av无码| 日韩一区二区三区高清视频 | 成人免费亚洲av在线| 涩欲国产一区二区三区四区| 国产精品亚洲二区亚瑟| 日韩精品无码去免费专区 | 亚洲日韩久热中文字幕| 久久精品日韩av无码| 99热精品毛片全部国产无缓冲 | 国产综合亚洲区在线观看| 国产成人精品国产成人亚洲| 精品久久久久久无码人妻蜜桃| 成人自拍小视频在线观看| 国产成人综合久久亚洲av| 精品少妇人妻av无码久久| 中文字幕有码无码AV| 中国熟妇牲交视频| 91亚洲精品一区二区三区| 专栏| a4yy私人毛片| 国产亚洲精品综合99久久| 亚洲av色香蕉一二三区| 国产精品久久久久乳精品爆 | 99久久99久久久精品久久| 内射一区二区三区四区| 欧美极品少妇×xxxbbb|