Linux文本三剑客(2)

文章目录

  • 一、Linux文本三剑客之awk
    • 使用方法
    • awk 的原理
      • 实例一:只查看test.txt文件(100行)内第20到第30行的内容(企业面试)
      • 实例二:已知test.txt文件内容为
    • BEGIN 和 END 模块
      • 实例一:统计/etc/passwd的账户人数
      • 实例二:统计某个文件夹下的文件占用的字节数
    • awk运算符
    • 常用 awk 内置变量
    • awk正则
    • awk 的 if、循环和数组
      • if
      • while
      • 数组
    • 常用字符串函数

一、Linux文本三剑客之awk

使用方法

awk '{pattern + action}' {filenames}

其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

awk 的原理

-F:指定分隔符

[root@localhost ~]# awk -F: '{print $0}' /etc/passwd

执行 awk 时,它依次对/etc/passwd 中的每一行执行 print 命令。
在这里插入图片描述

[root@localhost ~]# awk -F":" '{print $1}' /etc/passwd
[root@localhost ~]# awk -F":" '{print $1 $3}' /etc/passwd
[root@localhost ~]# awk -F":" '{print $1" " $3}' /etc/passwd
[root@localhost ~]# awk -F":" '{print "username:"$1"\t\tuid:" $3}' /etc/passwd

-F参数:指定分隔符,可指定一个或多个

print 后面做字符串的拼接

实例一:只查看test.txt文件(100行)内第20到第30行的内容(企业面试)

sed -n ‘20,30p’

[root@localhost ~]# seq 100 > test.txt
[root@localhost ~]# awk '{if(NR>=20 && NR<=30) print $1}' test.txt
20
21
22
23
24
25
26
27
28
29
30
 
# nl /etc/passwd | tail -n +20 |head -n 10

实例二:已知test.txt文件内容为

[root@localhost ~]# cat test.txt
I am aaron, my qq is 1234567

请从该文件中过滤出’aaron’字符串与1234567,最后输出的结果为:aaron 1234567

[root@localhost ~]# awk -F '[ ,]+' '{print $3" "$8}' test.txt #用[]可以放多个分隔符
aaron 1234567
等效
[root@localhost ~]# awk -F ',' '{print $1" "$2}' test.txt|awk '{print $3 " " $7}'

BEGIN 和 END 模块

实例一:统计/etc/passwd的账户人数

awk 'BEGIN {count=0;print "[start] user count is ",count}{count++;print $0} END{print "[end] user count is ",count}' /etc/passwd

count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0

[root@localhost ~]# awk '{count++;print $0;} END{print "user count is ",count}' /etc/passwd

实例二:统计某个文件夹下的文件占用的字节数

[root@localhost ~]# ll | awk 'BEGIN {size=0} {size=size+$5} END{print "size is ",size}'
size is 1468
[root@localhost ~]# ll | awk 'BEGIN {size=0} {size=size+$5} END{print "size is ",size/1024/1024,"M"}'
size is 0.00139999 M

awk运算符

运算符描述
赋值运算符
= += -= *= /= %= ^= **=赋值语句
逻辑运算符
¦¦逻辑或
&&逻辑与
正则运算符
~ !~匹配正则表达式和不匹配正则表达式
关系运算符
< <= > >= != ==关系运算符
算数运算符
+ -加,减
* / &乘,除与求余
+ - !一元加,减和逻辑非
^ ***求幂
++ –增加或减少,作为前缀或后缀
其他运算符
$字段引用
空格字符串链接符
?:三目运算符
ln数组中是否存在某键值

awk 赋值运算符:a+=5;等价于: a=a+5;其他同类

[root@node-1 ~]# awk 'BEGIN{a=5;a+=5;print a}'
10

awk逻辑运算符:判断表达式 a>2&&b>1为真还是为假,后面的表达式同理

[root@node-1 ~]# awk 'BEGIN{a=1;b=2;print (a>2&&b>1,a=1||b>1)}'
0 1

awk正则运算符:

[root@node-1 ~]# awk 'BEGIN{a="100testaa";if(a~/100/) {print "OK"}}'
OK

关系运算符:

如: > < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比较。两个都为数字 才转为数值比较。字符串比较:按照ascii码顺序比较。

[root@node-1 ~]# awk 'BEGIN{a="11";if(a>=9){print"OK"}}'
[root@node-1 ~]# awk 'BEGIN{a=11;if(a>=9){print"OK"}}'
OK
[root@node-1 ~]# awk 'BEGIN{a;if(a>=b){print"OK"}}'
OK

awk 算术运算符:

说明,所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0。

[root@node-1 ~]# awk 'BEGIN{a="b";print a++,++a}'
0 2
[root@node-1 ~]# awk 'BEGIN{a="20b4";print a++,++a}'
20 22

这里的a++ , ++a与javascript语言一样:a++是先赋值加++;++a是先++再赋值

三目运算符 ?:

[root@node-1 ~]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}'
ok
[root@node-1 ~]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}'
err

常用 awk 内置变量

变量名属性
$0当前记录
$1~ $n当前记录的第n个字段
FS输入字段分割符 默认是空格
RS输入记录分割符 默认为换行符
NF当前记录中的字段个数,就是有多少列
NR已经读出的记录数,就是行号,从1开始
OFS输出字段分割符 默认也是空格
ORS输出的记录分割符 默认为换行符

注:内置变量很多,参阅相关资料

字段分隔符 FS

FS=“\t” 一个或多个 Tab 分隔

[root@node-1 ~]# cat tab.txt
aa bb cc
[root@node-1 ~]# awk 'BEGIN{FS="\t+"}{print $1,$2,$3}' tab.txt
aa bb cc

FS=“[[:space:]+]” 一个或多个空白空格,默认的,匹配到不符合的就停止

[root@node-1 ~]# awk -F [[:space:]+] '{print $1,$2,$3,$4,$5}' tab.txt
aa bb cc
[root@node-1 ~]# awk -F [[:space:]+] '{print $1,$2}' tab.txt
aa bb

FS=“[” “:]+” 以一个或多个空格或:分隔

[root@node-1 ~]# awk -F [" ":]+ '{print $1,$2,$3}' hello.txt
root x 0

字段数量 NF :显示满足用:分割,并且有8个字段的

[root@node-1 ~]# awk -F ":" 'NF==8{print $0}' hello.txt
bin:x:1:1:bin:/bin:/sbin/nologin:888

记录数量 NR

[root@node-1 ~]# ifconfig br0 | awk -F [" ":]+ 'NR==2{print $3}'
192.168.0.241

RS 记录分隔符变量

将 FS 设置成"\n"告诉 awk 每个字段都占据一行。通过将 RS 设置成"",还会告诉 awk每个地址记录都由空白行分隔。

[root@node-1 ~]# cat awk.txt
#!/bin/awk
BEGIN {
	FS="\n"
	RS=""
}
{
	print $1","$2","$3
}
[root@node-1 ~]# awk -f awk.txt recode.txt

在""分割符之内,符合\n分割的会被打印出来

OFS 输出字段分隔符

[root@node-1 ~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2,$3}' hello.txt
root#x#0
bin#x#1

ORS 输出记录分隔符

[root@node-1 ~]# cat awk.txt
#!/bin/awk
BEGIN {
	FS="\n"
	RS=""
	ORS="\n\n"
}
{
	print $1","$2","$3
}
[root@node-1 ~]# awk -f awk.txt recode.txt
Jimmy the Weasel,100 Pleasant Drive,San Francisco,CA 123456

Big Tony,200 Incognito Ave.,Suburbia,WA 64890

awk正则

元字符功能示例解释
^首航定位符/^root/匹配所有以root开头的行
|行尾定位符|/root/匹配所有以root结尾的行
.匹配任意单个字符/r…t/匹配字母r,然后两个任意字符,再以t结尾的行
*匹配0个或多个前导字符(包括回车)/a*ool/匹配0个或多个a之后紧跟着ool的行,比如ool,aaaaool等
+匹配1个或多个前导字符/a+b/ab, aaab
?匹配0个或1个前导字符/a?b/b,ab
[]匹配指定字符组内的任意一个字符/1/匹配以a或b或c开头的行
[^]匹配不在指定字符组内任意一个字符/[abc]/匹配不以字母a或b或c开头的行
()子表达式组合/(rool)+/表示一个或多个rool组合,当有一些字符需要组合时,使用括号括起来
¦或者的意思/(root)\¦B/匹配root或者B的行
\转义字符/a///匹配a//
,!匹配,不匹配的条件语句$1~/root/匹配第一个字段包含字符root的所有记录
x{m}x{m,}x{m,n}x重复m次x重复至少m次x重复至少m次,但是不超过n次/(root){3}//(root){3,}//(root){3,6}/

正则应用

规则表达式

awk '/REG/{action} ' file ,/REG/为正则表达式,可以将$0 中,满足条件的记录送入到:action进行处理

[root@node-1 ~]# awk '/root/{print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@node-1 ~]# awk -F ":" '$5~/root/{print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@node-1 ~]# ifconfig br0 | awk 'BEGIN{FS="[[:space:]:]+"} NR==2{print$3}'
192.168.0.241

布尔表达式

awk '布尔表达式{action}' file 仅当对前面的布尔表达式求值为真时, awk 才执行代码块。

[root@node-1 ~]# awk -F: '$1=="root"{print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@node-1 ~]# awk -F: '($1=="root")&&($5=="root"){print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

awk 的 if、循环和数组

if

条件语句

awk 提供了非常好的类似于 C 语言的 if 语句。

{
	if ($1=="foo"){
	if ($2=="foo"){
		print"uno"
	}else{
		print"one"
	}
	}elseif($1=="bar"){
		print "two"
	}else{
		print"three"
	}
}

使用 if 语句还可以将代码:

! /matchme/ { print $1 $3 $4 }

转换成:

{
	if ( $0 !~ /matchme/ ) {
		print $1 $3 $4
	}
}

while

循环结构

我们已经看到了 awk 的 while 循环结构,它等同于相应的 C 语言 while 循环。 awk 还有"do…while"循环,它在代码块结尾处对条件求值,而不像标准 while 循环那样在开始处求值。

它类似于其它语言中的"repeat…until"循环。以下是一个示例:

do…while 示例

{
	count=1do {
		print "I get printed at least once no matter what"
	} while ( count !=1 )
}

与一般的 while 循环不同,由于在代码块之后对条件求值, "do…while"循环永远都至少执行一次。换句话说,当第一次遇到普通 while 循环时,如果条件为假,将永远不执行该循环。

for 循环

awk 允许创建 for 循环,它就象 while 循环,也等同于 C 语言的 for 循环:

for ( initial assignment; comparison; increment ) {
	code block
}

以下是一个简短示例:

for ( x=1;x<=4;x++ ) {
	print "iteration", x
}

break 和 continue

此外,如同 C 语言一样, awk 提供了 break 和 continue 语句。使用这些语句可以更好地控制 awk 的循环结构。

#!/bin/awk
BEGIN{
x=1
while(1) {
	print "iteration",x
	if ( x==10 ){
		break
	}
	x++
	}
}

continue 语句补充了 break

x=1
while (1) {
	if ( x==4 ) {
	x++
	continue
	}
	print "iteration", x
	if ( x>20 ) {
		break
	}
	x++
}

continue在for中使用

#!/bin/awk
BEGIN{
for (x=1;x<=21;x++){
if (x==4){
	continue
}
	print "iteration",x
}
}

数组

AWK 中的数组都是关联数组,数字索引也会转变为字符串索引

在awk中,数组叫关联数组,与我们在其它编程语言中的数组有很大的区别。关联数组,简单来说,类似于python语言中的dict、java语言中的map,其下标不再局限于数值型,而可以是字符串,即下标为key,value=array[key]。竟然为key,那其下标也不再是有序的啦。

#!/bin/awk
BEGIN{
	cities[1]="beijing"
	cities[2]="shanghai"
	cities["three"]="guangzhou"
	for( c in cities) {
		print cities[c]
	}
	print cities[1]
	print cities["1"]
	print cities["three"]
}

用 awk 中查看服务器连接状态并汇总

[root@node-1 ~]# netstat -an|awk '/^tcp/{++s[$NF]}END{for(a in s)print
a,s[a]}'
LISTEN 8
ESTABLISHED 1

常用字符串函数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

字符串函数的应用

在 info 中查找满足正则表达式, /[0-9]+/ 用”!”替换,并且替换后的值,赋值给 info

[root@node-1 ~]# awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}' 
this is a test!test!

如果查找到数字则匹配成功返回 ok,否则失败,返回未找到

[root@node-1 ~]# awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'
ok

从第 4 个 字符开始,截取 10 个长度字符串

[root@node-1 ~]# awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'
s is a tes

分割 info,动态创建数组 tA,awk for …in 循环,是一个无序的循环。 并不是从数组下标1…n 开始

[root@node-1 ~]# awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}'
4
4 test
1 this
2 is
3 a

  1. abc ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/382712.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【单片机】简单的自定义延时程序设计(代码演示)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY…

2、6作业

TCP和UDP的区别 TCP和UDP都是通信协议 TCP提供有连接的&#xff0c;稳定的&#xff0c;无误码无失真无乱序无丢失的通信 UDP提供无连接的&#xff0c;尽力的&#xff0c;可能误码可能乱序&#xff0c;可能丢失的通信 TCP每发一个数据包就需要对方回应一个应答包&#xff0c…

C++重新入门-C++判断语句

目录 1.if语句 嵌套 if 语句 2.switch语句 工作原理 语法 示例 3.三元运算符 示例 注意事项 判断结构要求程序员指定一个或多个要评估或测试的条件&#xff0c;以及条件为真时要执行的语句&#xff08;必需的&#xff09;和条件为假时要执行的语句&#xff08;可选的&…

Rust基础拾遗--核心功能

Rust基础拾遗 前言1.所有权与移动1.1 所有权 2.引用3.特型与泛型简介3.1 使用特型3.2 特型对象3.3 泛型函数与类型参数 4.实用工具特型5.闭包 前言 通过Rust程序设计-第二版笔记的形式对Rust相关重点知识进行汇总&#xff0c;读者通读此系列文章就可以轻松的把该语言基础捡起来…

推荐知识付费源码,梦想贩卖机升级版

梦想贩卖机升级版&#xff0c;变现宝吸收了资源变现类产品的许多优势&#xff0c;并剔除了那些无关紧要的元素&#xff0c;使得本产品在运营和变现能力方面实现了质的飞跃。多领域素材资源知识变现营销裂变独立版本。 演示地址&#xff1a;runruncode.com/rjcx/19689.html

电商小程序03登录页面开发

目录 1 创建应用2 创建页面3 首页功能搭建4 登录页搭建5 设置叠加效果总结 小程序开发在经过需求分析和数据源设计之后&#xff0c;就可以进入到页面开发的阶段了。首先我们需要开发登录的功能。 登录功能要求用户输入用户名和密码&#xff0c;勾选同意用户协议和隐私协议&…

第77讲用户管理功能实现

用户管理功能实现 前端&#xff1a; views/user/index.vue <template><el-card><el-row :gutter"20" class"header"><el-col :span"7"><el-input placeholder"请输入用户昵称..." clearable v-model"…

JVM-类加载器 双亲委派机制

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 什么是JVM JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&a…

Peter算法小课堂—背包问题

我们已经学过好久好久的动态规划了&#xff0c;动态规划_Peter Pan was right的博客-CSDN博客 那么&#xff0c;我用一张图片来概括一下背包问题。 大家有可能比较疑惑&#xff0c;优化决策怎么优化呢&#xff1f;答案是&#xff0c;滚动数组&#xff0c;一个神秘而简单的东西…

AI:125-基于深度学习的航拍图像中地物变化检测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

uniapp vue3怎么调用uni-popup组件的this.$refs.message.open() ?

vue2代码 <!-- 提示信息弹窗 --><uni-popup ref"message" type"message"><uni-popup-message :type"msgType" :message"messageText" :duration"2000"></uni-popup-message></uni-popup>typ…

【集合系列】TreeMap 集合

TreeMap 集合 1. 概述2. 方法3. 遍历方式4. 排序方式5. 代码示例16. 代码示例27. 代码示例38. 注意事项9. 源码分析 其他集合类 父类 Map 集合类的遍历方式 TreeSet 集合 具体信息请查看 API 帮助文档 1. 概述 TreeMap 是 Java 中的一个集合类&#xff0c;它实现了 SortedMap…

ChatGPT高效提问—prompt常见用法(续篇九)

ChatGPT高效提问—prompt常见用法(续篇九) ​ 如何准确地向大型语言模型提出问题,使其更好地理解我们的意图,从而得到期望的答案呢?编写有效的prompt的技巧,精心设计的prompt,获得期望的的答案。 1.1 增加条件 ​ 在各种prompt技巧中,增加条件是最常用的。在prompt中…

人工智能之大数定理和中心极限定理

大数定律 大数定律&#xff1a;是一种描述当试验次数很大时所呈现的概率性致的定律&#xff0c;由概率统计定义“频率收敛于概率”引申而来。换而言之&#xff0c;就是n个独立分布的随机变量其观察值的均值依概率收敛于这些随机变量所属分布的理论均值&#xff0c;也就是总体均…

精读《js 模块化发展》

1 引言 如今&#xff0c;Javascript 模块化规范非常方便、自然&#xff0c;但这个新规范仅执行了 2 年&#xff0c;就在 4 年前&#xff0c;js 的模块化还停留在运行时支持&#xff0c;10 年前&#xff0c;通过后端模版定义、注释定义模块依赖。对经历过来的人来说&#xff0c;…

区间dp 笔记

区间dp一般是先枚举区间长度&#xff0c;再枚举左端点&#xff0c;再枚举分界点&#xff0c;时间复杂度为 环形石子合并 将 n 堆石子绕圆形操场排放&#xff0c;现要将石子有序地合并成一堆。 规定每次只能选相邻的两堆合并成新的一堆&#xff0c;并将新的一堆的石子数记做该…

qt学习:串口

头文件 #include <QSerialPort> #include <QSerialPortInfo> 模块 QT core gui serialport 编程步骤 配置一个ui界面&#xff0c;五个QComboBox和一个按钮和一个QTextEdit 添加一个成员 private:QSerialPort *serial; 在构造函数中初始化ui端口列表和…

【数据结构和算法】--- 基于c语言排序算法的实现(2)

目录 一、交换排序1.1 冒泡排序1.2 快速排序1.2.1 hoare法1.2.2 挖坑法1.2.3 前后指针法 1.3 快速排序优化1.3.1 三数取中法选key1.3.2 递归到小的子区间使用插入排序 1.4 快排非递归版 二、归并排序2.1 归并排序2.1.1 递归版2.1.2 非递归版 一、交换排序 基本思想&#xff1a…

hexo 博客搭建以及踩雷总结

搭建时的坑 文章置顶 安装一下这个依赖 npm install hexo-generator-topindex --save然后再文章的上面设置 top: number&#xff0c;数字越大&#xff0c;权重越大&#xff0c;也就是越靠顶部 hexo 每次推送 nginx 都访问不到 宝塔自带的 nginx 的 config 里默认的角色是 …

磁盘分区和挂载

一、分区概念 1、基本概念 (1) 一块硬盘最多只能有4个主分区 (2) 其中一个(且最多只能有一个)主分区能作为扩展分区,而扩展分区不能写入数据,只能包含逻辑分区 2、格式化 分区之后的磁盘并不能直接使用&#xff0c;而是需要先进行格式化&#xff0c;又称为逻辑格式化。它是指…