轨道
/
jq
jq
/
练习
/
日志行解析器
日志行解析器

日志行解析器

学习练习

简介

字符串

回想一下,jq支持与 JSON 相同的数据类型。 JSON 把字符串描述为:

字符串是由零个或多个 Unicode 字符组成的序列,用双引号括起来,并使用反斜杠转义。

转义序列

在字符串中,可以使用反斜杠字符来嵌入“特殊”字符:

  • \"表示一个字面量双引号,
  • \\表示一个字面量反斜杠,
  • 空白字符\n、\t、\r、\f、\b
  • Unicode 字符\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。

经常需要把字符串转换成字符数组。 有两种方法:

  1. 按空字符串拆分

    "Hi friend 😀" / ""   # => ["H","i"," ","f","r","i","e","n","d"," ","😀"]
    
  2. 用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>"。

日志级别有三种:

  • INFO
  • WARNING
  • ERROR

你有三个任务,每个任务都会给你一条日志行,让你对它做点什么。解决这些任务的方法有很多,从上文的示例中挑一个你最喜欢的技术,看看能想出什么办法。

1. 从日志行中获取消息

实现message函数,返回日志行的消息:

"[ERROR]: Invalid operation" | message
# => "Invalid operation"

开头和结尾的空白字符都应去掉:

"[WARNING]:  Disk almost full\r\n" | message
# => "Disk almost full"

2. 从日志行中获取日志级别

实现log_level函数,返回日志行的日志级别,返回值应为小写:

"[ERROR]: Invalid operation" | log_level
# => "error"

3. 重新格式化日志行

实现reformat函数,重新格式化日志行,把消息放在前面,日志级别用括号放在它后面:

"[INFO]: Operation completed" | reformat
# => "Operation completed (info)"
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
jq Exercism

准备好开始 日志行解析器 了吗?

注册 Exercism,借助 12 个概念75 个练习 和真人导师指导,学习并掌握 jq,全部免费。