前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux实战(一)

linux实战(一)

作者头像
拓荒者
发布2019-06-15 15:16:20
2.2K0
发布2019-06-15 15:16:20
举报
文章被收录于专栏:运维经验分享运维经验分享

linux实战(一)----日志的截取-----文本过滤器grep、文本流式编辑器sed、报表生成器awk的运用

2015年12月25日 16:28:50 张小凡vip 阅读数 5404更多

所属专栏: linux基础与shell编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q383965374/article/details/50394765

我们前面已经学习过 linux的性能查询(top),以及网络端口查询(netstat)命令等等。

怎么让我们查询到的信息按   我们需要的格式 显示生成。

就是我们本章 需要 学习练习的。

主要是grep,sed,awk3个命令的运用。

grep主要负责搜索

sed主要负责处理行

awk主要复杂处理列

我们在下一章的内容再来学习实例,如果用这几个命令来进行性能监控等。

grep

作用

grep命令可以指定文件中搜索特定的内容,并将含有这些内容的行标准输出。

grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。

格式

grep [options]

[options]主要参数: -c:只输出匹配行的计数。 -I:不区分大小写(只适用于单字符)。 -h:查询多文件时不显示文件名。 -l:查询多文件时只输出包含匹配字符的文件名。 -n:显示匹配行及行号。 -s:不显示不存在或无匹配文本的错误信息。 -v:显示不包含匹配文本的所有行。

pattern正则表达式主要参数: \:忽略正则表达式中特殊字符的原有含义。 ^:匹配正则表达式的开始行。 $: 匹配正则表达式的结束行。 \:到匹配正则表达式的行结束。 [ ]:单个字符,如[A]即A符合要求。 [ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求。 。:所有的单个字符。 * :有字符,长度可以为0。

 ....      保存已匹配的字符

正则表达式是Linux/Unix系统中非常重要的概念。正则表达式(也称为“regex”或“regexp”)是一个可以描述一类字符串的模式(Pattern)。

如果一个字符串可以用某个正则表达式来描述,我们就说这个字符和该正则表达式匹配(Match)。

这和DOS中用户可以使用通配符“*”代表任意字符类似。

在Linux系统上,正则表达式通常被用来查找文本的模式,以及对文本执行“搜索-替换”操作和其它功能。

实例

代码语言:javascript
复制
$ ls -l | grep '^a'

通过管道过滤ls -l输出的内容,只显示以a开头的行。

代码语言:javascript
复制
$ grep 'test' d*

显示所有以d开头的文件中包含test的行。

代码语言:javascript
复制
$ grep 'test' aa bb cc

显示在aa,bb,cc文件中匹配test的行。

代码语言:javascript
复制
$ grep '[a-z]\{5\}' aa

显示aa文件中所有包含每个字符串有5个连续小写字符的字符串的行。

代码语言:javascript
复制
$ grep 'w\(es\)t.*\1' aa

如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个\1 ,\1也就是es,因为前面把es存储到了内存并默认标记为1了,找到就显示该行。如果用egrep或grep -E,就不用"\"号进行转义,直接写成'w(es)t.*\1'就可以了。

sed

作用

sed 常常用于一整个行的处理。sed是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

格式

sed [options] 'command' file(s)   sed [options] -f scriptfile file(s)  

[options]主要参数

-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。

-e :直接在命令列模式上进行 sed 的动作编辑; -f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作; -r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法) -i :直接修改读取的文件内容,而不是输出到终端。

'command'主要参数

a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~ c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行! d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚; i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行); p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~ s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

pattern正则表达式主要参数

 ^    行首定位符           

/^my/  匹配所有以my开头的行

 $ 行尾定位符

 /my$/  匹配所有以my结尾的行

 . 匹配除换行符以外的单个字符 

/m..y/  匹配包含字母m,后跟两个任意字符,再跟字母y的行

 * 匹配零个或多个前导字符

 /my*/  匹配包含字母m,后跟零个或多个y字母的行

 []   匹配指定字符组内的任一字符

/[Mm]y/  匹配包含My或my的行

 [^]  匹配不在指定字符组内的任一字符

/[^Mm]y/  匹配包含y,但y之前的那个字符不是M或m的行

 ....      保存已匹配的字符     

1,20s/youyouself/\1r/  标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。

 &      保存查找串以便在替换串中引用

s/my/**&**/  符号&代表查找串。my将被替换为**my**

 \<      词首定位符      

 /\<my/  匹配包含以my开头的单词的行

 \>      词尾定位符      

/my\>/  匹配包含以my结尾的单词的行

 x\{m\} 连续m个x  

 /9\{5\}/ 匹配包含连续5个9的行

 x\{m,\}      至少m个x      

/9\{5,\}/  匹配包含至少连续5个9的行

 x\{m,n\}     至少m个,但不超过n个     

/9\{5,7\}/  匹配包含连续5到7个9的行

定址

定址用于决定对哪些行进行编辑。地址的形式可以是数字、正则表达式、或二者的结合。如果没有指定地址,sed将处理输入文件的所有行。  地址是一个数字,则表示行号;是“$"符号,则表示最后一行。

实例

删除d命令

代码语言:javascript
复制
$ sed '2d' example

删除example文件的第二行。

代码语言:javascript
复制
$ sed '2,$d' example

删除example文件的第二行到末尾所有行。

代码语言:javascript
复制
$ sed '$d' example

删除example文件的最后一行。

代码语言:javascript
复制
$ sed '/test/'d example

删除example文件所有包含test的行。

替换s命令

代码语言:javascript
复制
$ sed 's/test/mytest/g' example

在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。

代码语言:javascript
复制
$ sed -n 's/^test/mytest/p' example

(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。

代码语言:javascript
复制
$ sed 's/^192.168.0.1/&localhost/' example

&;符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加localhost,变成192.168.0.1localhost。

代码语言:javascript
复制
$ sed -n 's/\(love\)able/\1rs/p' example

love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。

代码语言:javascript
复制
$ sed 's#10#100#g' example

不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。

选定行的范围逗号

代码语言:javascript
复制
$ sed -n '/test/,/check/p' example

所有在模板test和check所确定的范围内的行都被打印。

代码语言:javascript
复制
$ sed -n '5,/^test/p' example

打印从第五行开始到第一个包含以test开始的行之间的所有行。

代码语言:javascript
复制
$ sed '/test/,/check/s/$/sed test/' example

对于模板test和west之间的行,每行的末尾用字符串sed test替换。

多点编辑e命令

代码语言:javascript
复制
$ sed -e '1,5d' -e 's/test/check/' example

(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。

代码语言:javascript
复制
$ sed --expression='s/test/check/' --expression='/love/d' example

一个比-e更好的命令是--expression。它能给sed表达式赋值。

从文件读入r命令

代码语言:javascript
复制
$ sed '/test/r file' example

file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。

写入文件w命令

代码语言:javascript
复制
$ sed -n '/test/w file' example

在example中所有包含test的行都被写入file里。

追加命令a命令

代码语言:javascript
复制
$ sed '/^test/a\\this is a test line'  example

在example文件中'this is a test line'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。

插入i命令

代码语言:javascript
复制
$ sed '/test/i\\new line-------------------------'   example

如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。

下一个n命令

代码语言:javascript
复制
$ sed '/test/{ n; s/aa/bb/; }'  example

如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。

变形y命令

代码语言:javascript
复制
$ sed '1,10y/abcde/ABCDE/' example

把1--10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。

退出q命令

代码语言:javascript
复制
$ sed '10q' example

打印完第10行后,退出sed。

保持和获取h命令和G命令

代码语言:javascript
复制
$ sed -e '/test/h' -e '$G example

在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。

保持和互换h命令和x命令

代码语言:javascript
复制
$ sed -e '/test/h' -e '/check/x' example

互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。

awk

作用

 awk 比较倾向于一行当中分成数个『栏位』(或者称为一个域,也就是一列)来处理。awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

格式

awk [-F  field-separator]  'commands'  input-file(s) 其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。 在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

commands

awk的命令非常多,因为它甚至可以算是一个编程语言。我们这里就不详细讲述了。后面的实例学习中会了解到一部分常用的命令。

这里大概给出awk中的一些学习目录如下:

print和printf

awk中同时提供了print和printf两种打印输出的函数。 其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。 printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

awk的环境变量

变量描述 $n 当前记录的第n个字段,字段间由FS分隔。 $0 完整的输入记录。 ARGC 命令行参数的数目。 ARGIND 命令行中当前文件的位置(从0开始算)。 ARGV 包含命令行参数的数组。 CONVFMT 数字转换格式(默认值为%.6g) ENVIRON 环境变量关联数组。 ERRNO 最后一个系统错误的描述。 FIELDWIDTHS 字段宽度列表(用空格键分隔)。 FILENAME 当前文件名。 FNR 同NR,但相对于当前文件。 FS 字段分隔符(默认是任何空格)。 IGNORECASE 如果为真,则进行忽略大小写的匹配。 NF 当前记录中的字段数。 NR 当前记录数。 OFMT 数字的输出格式(默认值是%.6g)。 OFS 输出字段分隔符(默认值是一个空格)。 ORS 输出记录分隔符(默认值是一个换行符)。 RLENGTH 由match函数所匹配的字符串的长度。 RS 记录分隔符(默认是一个换行符)。 RSTART 由match函数所匹配的字符串的第一个位置。 SUBSEP 数组下标分隔符(默认值是\034)。

awk运算符

运算符 描述 = += -= *= /= %= ^= **= 赋值 ?: C条件表达式 || 逻辑或 && 逻辑与 ~ ~! 匹配正则表达式和不匹配正则表达式 < <= > >= != == 关系运算符 空格 连接 + - 加,减 * / & 乘,除与求余 + - ! 一元加,减和逻辑非 ^ *** 求幂 ++ -- 增加或减少,作为前缀或后缀 $ 字段引用 in 数组成员

专属正则表达式元字符

一般通用的元字符集就不讲了,可参考我的Sed和Grep。以下几个是gawk专用的,不适合unix版本的awk。 \Y 匹配一个单词开头或者末尾的空字符串。 \B 匹配单词内的空字符串。 \< 匹配一个单词的开头的空字符串,锚定开始。 \> 匹配一个单词的末尾的空字符串,锚定末尾。 \w

匹配一个字母数字组成的单词。 \W 匹配一个非字母数字组成的单词。 \‘ 匹配字符串开头的一个空字符串。 \' 匹配字符串末尾的一个空字符串。

awk编程

下面列举awk编程需要了解的东西:

变量 BEGIN模块 END模块 重定向和管道 条件语句 if语句 if/else语句,用于双重判断。 if/else else if语句,用于多重判断。 循环 数组 下标与关联数组 awk的内建函数 字符串函数 时间函数 日期和时间格式说明符 内建数学函数 自定义函数

实例

截取单列

last会列出最近登录的情况, 仅取出前五行

假设last -n 5的输出如下

代码语言:javascript
复制
[root@www ~]# last -n 5
root     pts/1   192.168.1.100  Tue Feb 10 11:21   still logged in
root     pts/1   192.168.1.100  Tue Feb 10 00:46 - 02:28  (01:41)
root     pts/1   192.168.1.100  Mon Feb  9 11:41 - 18:30  (06:48)
dmtsai   pts/1   192.168.1.100  Mon Feb  9 11:41 - 11:41  (00:00)
root     tty1                   Fri Sep  5 14:09 - 14:10  (00:01)

如果只是显示最近登录的5个帐号  也就是第一列

代码语言:javascript
复制
#last -n 5 | awk  '{print $1}'
root
root
root
dmtsai
root

awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键",所以$1表示登录用户,$3表示登录用户ip,以此类推。

设置分隔符

默认域分隔符是"空白键" 或 "[tab]键",如果想用其它符合作分隔符,参照下例:

/etc/passwd中是用:分割的

如下:

代码语言:javascript
复制
#cat /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
daemon:x:2:2:daemon:/sbin:/sbin/nologin 
bin:x:1:1:bin:/bin:/sbin/nologin
sys:x:80:80:desktop:/var/lib/menu/kde:/sbin/nologin 

如果只是显示/etc/passwd的账户

代码语言:javascript
复制
#cat /etc/passwd |awk  -F ':'  '{print $1}'  
root
daemon
bin
sys

-F指定域分隔符为':'。     {print $1}输出第一列

显示多行

显示/etc/passwd的账户和账户对应的shell,显示时账户与shell之间以tab键分割

代码语言:javascript
复制
#cat /etc/passwd |awk  -F ':'  '{print $1"\t"$7}'
root    /bin/bash
daemon  /bin/sh
bin     /bin/sh
sys     /bin/sh

-F指定域分隔符为':'。     {print $1 "\t" $7} 输出第一列  tab  和 第7列

使用BEGIN END模块

显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh"。

代码语言:javascript
复制
#cat /etc/passwd |awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7} END {print "blue,/bin/nosh"}'
name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
blue,/bin/nosh

awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。

正则搜索

搜索/etc/passwd里有root关键字的所有行

代码语言:javascript
复制
#awk -F ':'  '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash

这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。 搜索支持正则,例如找root开头的: awk -F ':'  '/^root/' /etc/passwd

正则搜索显示单列

搜索/etc/passwd有root关键字的所有行,并显示对应的shell  也就是第7列

代码语言:javascript
复制
# awk -F ':'  '/root/{print $7}' /etc/passwd             
/bin/bash

这里指定了action{print $7}

awk环境变量的运用

我们上面提过都有哪些环境变量。 现在我们要统计/etc/passwd文件中的:文件名,每行的行号,每行的列数 使用到的变量参数如下: FILENAME           awk浏览的文件名 NR                 已读的记录数  也就是第几行 NF                 浏览记录的域的个数  也就是 共几列 $0 输出整行

代码语言:javascript
复制
#awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh

使用printf替代print

printf就是线使用占位符占位,后面再一起传入参数,可以让代码更加简洁,易读

代码语言:javascript
复制
awk  -F ':'  '{printf("filename:%s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

自定义变量

统计/etc/passwd的账户人数,每一行是一个账户,因为刚好awk是逐行遍历,所以我们自定义一个count自加就行。 当然 定义count为0需要在 awk逐行遍历之前  所以需要用BEGIN模块。

代码语言:javascript
复制
awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
[start]user count is  0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is  40

运算

我们需要统计某个文件夹下的文件占用的字节数 因为文件占用的字节数 在 ls -l命令中的第5列 所以我们使用如下命令:

代码语言:javascript
复制
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
[end]size is  8657198

如果以M为单位显示:

代码语言:javascript
复制
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}' 
[end]size is  8.25889 M

注意,统计不包括文件夹的子目录。

条件语句

统计某个文件夹下不等于4096的其它文件占用的字节数-----过滤4096大小的文件:

代码语言:javascript
复制
ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}' 
[end]size is  8.22339 M

数组

显示/etc/passwd的账户

代码语言:javascript
复制
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
0 root
1 daemon
2 bin
3 sys
4 sync
5 games
......

awk编程的内容极多,这里只罗列简单常用的用法,更多请参考 http://www.gnu.org/software/gawk/manual/gawk.html

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • linux实战(一)----日志的截取-----文本过滤器grep、文本流式编辑器sed、报表生成器awk的运用
  • grep
    • 作用
      • 格式
        • grep [options]
          • 实例
          • sed
            • 作用
              • 格式
                • [options]主要参数
                • 'command'主要参数
                • pattern正则表达式主要参数
              • 定址
                • 实例
                  • 删除d命令
                  • 替换s命令
                  • 选定行的范围逗号
                  • 多点编辑e命令
                  • 从文件读入r命令
                  • 写入文件w命令
                  • 追加命令a命令
                  • 插入i命令
                  • 下一个n命令
                  • 变形y命令
                  • 退出q命令
                  • 保持和获取h命令和G命令
                  • 保持和互换h命令和x命令
              • awk
                • 作用
                  • 格式
                    • commands
                  • 实例
                    • 截取单列
                    • 设置分隔符
                    • 显示多行
                    • 使用BEGIN END模块
                    • 正则搜索
                    • 正则搜索显示单列
                    • awk环境变量的运用
                    • 使用printf替代print
                    • 自定义变量
                    • 运算
                    • 条件语句
                    • 数组
                相关产品与服务
                腾讯云 BI
                腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档