回想一下,jq支援和 JSON 相同的資料型態。
JSON 把字串描述為:
字串是由零個或多個 Unicode 字元組成的序列,以雙引號包住,並使用反斜線跳脫。
在字串中,使用反斜線字元來嵌入「特殊」字元:
\" 字面上的雙引號,\\ 字面上的反斜線,\n、\t、\r、\f、\b
\uAAAA,其中 A 是十六進位數字想知道字元的數量,可以使用length函式。
$ jq -cn --args '$ARGS.positional[] | length' "Hello world!" "❄🌡🤧🤒🏥🕰😀"
12
7
想知道實際的_位元組_數量,可以使用utf8bytelength函式。
$ jq -cn --args '$ARGS.positional[] | utf8bytelength' "Hello world!" "❄🌡🤧🤒🏥🕰😀"
12
27
可以使用 slice 標記法來取出子字串。
語法是.[i:j]。
回傳的子字串長度為j - i,內容是從索引i(含)到索引j(不含)的字元。
任一個索引都可以是負數,此時會從字串尾端往回數。
任一個索引也可以省略,此時代表字串的開頭或結尾。
索引從 0 開始。
"abcdefghij"[3:6] # => "def"
"abcdefghij"[3:] # => "defghij"
"abcdefghij"[:-2] # => "abcdefgh"
使用+來連接字串:
"Hello" + " " + "world!"
# => "Hello world!"
當拿到的是字串陣列時,使用add:
["Hello", " ", "world!"] | add
# => "Hello world!"
"Hello beautiful world!" | split(" ") # => ["Hello", "beautiful", "world!"]
"Hello beautiful world!" / " " # => ["Hello", "beautiful", "world!"]
我們經常需要把字串轉成字元陣列。 有兩種做法:
用空字串分割
"Hi friend 😀" / "" # => ["H","i"," ","f","r","i","e","n","d"," ","😀"]
用explode拆成_碼點_陣列
"Hi friend 😀" | explode # => [72,105,32,102,114,105,101,110,100,32,128512]
使用index/1函式;索引從 0 開始。
"hello" | index("el")' # => 1
如果字串裡沒有這個子字串,結果會是null
"hello" | index("elk") # => null
在字串中,\(expression)這個序列會把該運算式的_結果_嵌入字串:
"The current datetime is \(now | strflocaltime("%c"))" # => "The current datetime is Wed Nov 16 17:06:33 2022"
使用ascii_downcase和ascii_upcase函式來改變字串的大小寫。
使用tonumber函式從字串建立數字。
如果字串無法轉成數字,就會拋出錯誤,因此可能需要用到try-catch。
$ jq -cn --args '$ARGS.positional[] | [., tonumber]' 42 3.14 oops 1e6 0xbeef
["42",42]
["3.14",3.14]
jq: error (at <unknown>): Invalid numeric literal at EOF at line 1, column 4 (while parsing 'oops')
$ echo $?
5
$ jq -cn --args '$ARGS.positional[] | try [., tonumber] catch "not a number"' 42 3.14 oops 1e6 0xbeef
["42",42]
["3.14",3.14]
"not a number"
["1e6",1000000]
"not a number"
請注意,JSON 數字並不包含某些語言支援的十六進位或八進位變化。
這些函式的詳細資訊請查閱手冊:
*
contains/1、inside/1、indices/1、index/1、rindex/1、startswith/1、endswith/1
lsrimstr/1、rtrimstr/1
@text、@json、@html、@uri、@csv、@tsv、@sh、@base64、@base64d
jq對正規表示式有豐富的支援:這會是之後某一單元的主題。