回想一下,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
可以使用切片表示法来提取子字符串。语法是 .[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对正则表达式有丰富的支持:这将是后面某一课的主题。