回想一下,jq支持与 JSON 相同的数据类型。
JSON 把字符串描述为:
字符串是由零个或多个 Unicode 字符组成的序列,用双引号括起来,并使用反斜杠转义。
在字符串中,可以使用反斜杠字符来嵌入“特殊”字符:
\"表示一个字面量双引号,\\表示一个字面量反斜杠,\n、\t、\r、\f、\b
\uAAAA,其中A是十六进制数字要查找字符的数量,可以使用length函数。
$ jq -cn --args '$ARGS.positional[] | length' "Hello world!" "❄🌡🤧🤒🏥🕰😀"
12
7
可以用切片表示法来提取子字符串。
语法是.[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!"
拆分使用split/1函数或/运算符:
"Hello beautiful world!" | split(" ") # => ["Hello", "beautiful", "world!"]
"Hello beautiful world!" / " " # => ["Hello", "beautiful", "world!"]
split/1的逆操作是join/1。
经常需要把字符串转换成字符数组。 有两种方法:
按空字符串拆分
"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]
implode是explode的逆操作。
使用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函数。
jq对正则表达式有丰富的支持:这将是后面某一课的主题。
在这个练习中,你将处理日志条目。
每条日志行都是一个格式如下的字符串:"[<LEVEL>]: <MESSAGE>"。
日志级别有三种:
INFOWARNINGERROR你有三个任务,每个任务都会给你一条日志行,让你对它做点什么。解决这些任务的方法有很多,从上文的示例中挑一个你最喜欢的技术,看看能想出什么办法。
实现message函数,返回日志行的消息:
"[ERROR]: Invalid operation" | message
# => "Invalid operation"
开头和结尾的空白字符都应去掉:
"[WARNING]: Disk almost full\r\n" | message
# => "Disk almost full"
实现log_level函数,返回日志行的日志级别,返回值应为小写:
"[ERROR]: Invalid operation" | log_level
# => "error"
实现reformat函数,重新格式化日志行,把消息放在前面,日志级别用括号放在它后面:
"[INFO]: Operation completed" | reformat
# => "Operation completed (info)"