十、shell编程之awk 下

本文详细介绍了awk命令的模式匹配,包括关系表达式、正则表达式、混合模式、BEGIN和END模式的使用。同时,讲解了awk中的控制语句,如if、while、for循环,以及break、continue、next和exit语句。此外,还讨论了awk如何处理数组和内置函数,如split、length、substr等,以及如何在awk程序中使用系统命令。通过对这些内容的学习,读者能够更深入地掌握awk在文本处理中的应用。

1.  awk的模式:

awk的基本语法:
awk [options]  'PATTERN { action }'  file1 file2, ...
awk中的匹配模式主要包括关系表达式、正则表达式、混合模式,BEGIN模式以及END模式等。

2.  关系表达式:

        awk提供了许多关系运算符,例如大于>、小于<或者等于==等。awk允许用户使用关系表达式作为匹配模式,当某个文本行满足关系表达式时,将会执行相应的操作。
示例:
[root@localhost test11]# cat file
liming 80
wangmei 70
zhangsan 90
lisi 81
[root@localhost test11]# awk '$2 > 80 {print}' file
zhangsan 90
lisi 81

 3.  正则表达式

        awk支持以正则表达式作为匹配模式,与sed一样,用户需要将正则表达式放在两条斜线之间,其基本语法如下:/regular_expression/。
示例:
[root@localhost test11]# awk '/^l|z/{print}' file
liming 80
zhangsan 90
lisi 81

4.   混合模式:

        awk不仅支持单个的关系表达式或者正则表达式作为模式,还支持使用逻辑运算符&&||或者!将多个表达式组合起来作为一个模式。其中,&&表示逻辑与,||表示逻辑或,!表示逻辑非。
[root@localhost test11]# awk  '/^l/ && $2>80 {print}'  file
lisi 81
5.  区间模式:
        awk还支持一种区间模式,也就是说通过模式可以匹配一段连续的文本行。区间模式的语法如下:
        
pattern1, pattern2
        其中,pattern1和pattern2都是前面所讲的匹配模式,可以是关系表达式,也可以是正则表达式等。当然,也可以是这些模式的混合形式。
示例:
[root@localhost test11]# awk  '/^liming/,$2==90 {print}'  file 
liming 80
wangmei 70
zhangsan 90

 注意:

            区间匹配是最短匹配,既当pattern1成立时会最短匹配pattern2成立的区间。

            若pattern1成立而pattern2不成立,则会匹配pattern1成立的记录以及一下的所有记录。

6.  BEGIN模式:

        BEGIN模式是一种特殊的内置模式,其成立的时机为awk程序刚开始执行,但是又尚未读取任何数据之前。因此,该模式所对应的操作仅仅被执行一次,当awk读取数据之后,BEGIN模式便不再成立。所以,用户可以将与数据文件无关,而且在整个程序的生命周期中,只需执行1次的代码放在BEGIN模式对应的操作中。
示例:
[root@localhost test11]# cat 1.awk
#!/bin/awk -f
BEGIN {print "hello,world"}
[root@localhost test11]# ./1.awk
hello,world

7.   END模式

        END模式是awk的另外一种特殊模式,该模式成立的时机与BEGIN模式恰好相反,它是在awk命令处理完所有的数据,即将退出程序时成立,在此之前,END模式并不成立。无论数据文件中包含多少行数据,在整个程序的生命周期中,该模式所对应的操作只被执行1次。因此,一般情况下,用户可以将许多善后工作放在END模式对应的操作中。
示例:
[root@localhost test11]# cat 2.awk
#! /bin/awk -f
BEGIN {
        print "scores report"
        print "================================="
}
{ print }
END {
        print "================================"
        print "printing is over"
}
[root@localhost test11]# ./2.awk  file
scores report
=================================
liming 80
wangmei 70
zhangsan 90
lisi 81
================================
printing is over

 8.  awk控制语句

        1>.  if语句的功能是根据用户指定的条件来决定执行程序的哪个分支,其语法如下:

if (expression)
        statement1
        statement2
else
        statement3
        statement4

         2>.  while语句是另外一种常用的循环结构,其语法如下:

while (expression)
{
        statement1
        statement2
...
}
        当表达式expression的值为真时,执行循环体中的statement1以及statement2等语句。如果循环体中只包含一条语句,则可以省略大括号。
        3>.  awk还支持另外一种while循环语句,其语法如下:
do {
        statement1
        statement2
...
}while (expression)

         同样,当表达式expression的值为真时执行循环体中的语句。

        4>.  for循环语句通常用在循环次数已知的场合中,其语法如下:
for(expression1; expression2; expression3)
{
        statement1
        statement2
        ...
}
for循环还可以用来遍历数组元素:
语法: for(变量 in 数组) {语句}

         在上面的语法中,表达式expression1通常用来初始化循环变量,表达式expression2通常用来指定循环执行的条件,表达式expression3通常用来改变循环变量的值。当表达式expression2的值为真时,执行循环体中的语句。

        5>.  break语句:用户可以通过使用break语句在适当的时机退出for以及while等循环结构,而不必等到循环结构自己退出。

        6>.  continue语句:continue语句的主要功能是跳过循环结构中该语句后面的尚未执行的语句。break语句与continue语句的功能有着明显的区别,前者是直接退出循环结构,而后者是跳过循环体中尚未执行的语句,重新执行下一次循环。
        7>.  next语句:next语句的功能与continue语句非常相似,但是next语句并不是用在循环结构中,而是用在整个awk程序中。当awk执行程序时,如果遇到next语句,则提前结束对本行文本的处理,awk会继续读取下一行数据,并且从第一个模式及其操作开始执行。
        8>.  exit语句:exit语句的功能是终止awk程序的执行。
9.  awk使用数组:
        1>.  读取数组array[index-expression]:
                index-expression可以使用任意字符串;需要注意的是,如果某数组元素事先不存在,那么在引用时,awk会自动创建此元素并初始化为空串;因此,要判断某数组中是否存在某元素,需要使用( index in array )的方式。
要遍历数组中的每一个元素,需要使用如下的特殊结构:
        for (var in array) { statement1, ... }
        其中,var用于引用数组下标,而不是元素值,并且只能是一个字符。
示例:
[root@localhost ~]# netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
ESTABLISHED 1
LISTEN 10
每出现一次被/^tcp/模式匹配到的行,数组S[$NF]就加1NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引。
        2>.  删除数组变量:从关系数组中删除数组索引需要使用delete命令。使用格式为:
delete  array[index]

10.   awk内置函数:

        1>.  split(string, array [, fieldsep [, seps ] ]):
        功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列;
示例:
[root@localhost ~]# date +%T | awk '{split($0,a,":");print a[1],a[2],a[3]}'
19 32 19

        2>. length([string]):

        功能:返回string字符串中字符的个数;
示例:
[root@localhost ~]#awk 'BEGIN{print length("uplooking")}'
9

        3>.   substr(string, start [, length]):

        功能:取string字符串中的子串,从start开始,取length个;start1开始计数;

示例:

[root@localhost ~]#awk 'BEGIN{print substr("uplooking",u,2)}'
up

        4>.   system(command)

        功能:执行系统command并将结果和执行命令后的状态码返回至awk命令;

示例:

[root@localhost ~]# awk 'BEGIN{print system("whoami")}'
root
0

        5>. systime():        

        功能:取系统当前时间;
示例:
[root@localhost ~]# awk 'BEGIN{print systime()}'
1658489640

        6>. tolower(string) :

        功能:将s中的所有字母转为小写;

示例:

[root@localhost ~]# awk 'BEGIN{print tolower("WWW.baidu.COM")}'
www.baidu.com

        7>. toupper(s):

        功能:将s中的所有字母转为大写;
示例:
[root@localhost ~]# awk 'BEGIN{print toupper("WWW.baidu.COM")}'
WWW.BAIDU.COM
ReactReact Native 中,`setState` 的调用会触发一系列内部机制来更新组件的状态和视图。尽管两者在机制上有很多相似之处,但也存在一些关键差异。 ### 更新状态对象 当调用 `setState` 方法时,ReactReact Native 都会将传入的新状态对象与当前的状态对象进行合并,生成一个新的状态对象。如果新的状态对象与旧的状态对象在浅比较下是相等的,那么框架会认为状态没有发生变化,并跳过后续的更新操作。如果状态确实发生了变化,那么新的状态对象会替换掉旧的状态对象,并触发组件的更新过程[^2]。 ### 虚拟 DOM 与 Diff 算法 在 React 中,状态更新后会触发组件的重新渲染,React 会根据新的状态重新计算组件的虚拟 DOM 树。然后,React 使用高效的 diff 算法将新的虚拟 DOM 树与旧的虚拟 DOM 树进行比较,找出两者之间的差异。这些差异会被高效地应用到真实的 DOM 上,实现最小化的 DOM 操作,从而提高性能[^2]。 React Native 的情况略有不同,因为它并不直接操作真实的 DOM,而是将更新应用到原生组件上。React Native 使用虚拟 DOM 来跟踪 UI 的变化,并通过 JavaScript 到原生的桥接机制将这些变化传递给平台相关的原生组件,如 Android 上的 View 或 iOS 上的 UIView。这种机制允许 React Native 在不同平台上提供一致的用户体验[^1]。 ### 异步更新与批量处理 ReactReact Native 都支持 `setState` 的异步更新,这意味着 `setState` 调用不会立即更新状态,而是将更新操作排队等待执行。这样的设计可以提高性能,因为它允许框架将多个状态更新合并成一次性的更新操作。如果在一次事件循环中多次调用 `setState`,后面的调用可能会覆盖前面的调用,因为它们会在同一批处理中被集中处理[^3]。 ### 获取更新后的状态 由于 `setState` 是异步的,因此不建议在调用 `setState` 后立即访问 `this.state` 来获取更新后的状态。如果需要在状态更新后执行某些操作,应该将这些操作放在 `setState` 方法的第二个参数中,这是一个可选的回调函数,在状态更新完成后会被调用。 ### 示例代码 下面是一个简单的示例,展示了如何在 `setState` 后执行回调函数: ```javascript this.setState({ count: this.state.count + 1 }, () => { console.log('State has been updated to:', this.state.count); }); ``` 在这个例子中,当状态 `count` 更新完成后,提供的回调函数会被执行,并打印出最新的状态值。 通过上述机制,ReactReact Native 提供了一种高效且灵活的方式来管理组件的状态和视图更新。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值