Ubuntu小技巧15--awk命令详解

2024-05-31 00:18
文章标签 ubuntu 15 awk 详解 技巧 命令

本文主要是介绍Ubuntu小技巧15--awk命令详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Ubuntu小技巧15--awk命令详解

  • Ubuntu小技巧15--awk命令详解
  • 1 基本介绍
    • 1.1 工作原理
    • 1.2 使用格式
  • 2 常用功能介绍
    • 2.1 格式化输出
    • 2.2 从文件获取awk命令
    • 2.3 模式和动作
    • 2.4 正则表达
  • 3 经典案例
  • 4 注意事项
  • 5 说明

Ubuntu小技巧15–awk命令详解

1 基本介绍

Awk是一种用于处理数据和生成报告的UNIX编程语言。 Nawk是awk的较新版本,而gawk是Linux上使用的GNU版本。awk 的数据可以来自标准输入、一个或多个文件,也可以来自一个程序的输出。 其既可以在命令行上进行一些简单的操作,也可以将Awk写入到大型应用程序中。 由于awk可以处理数据,所以它是在shell脚本和管理小型数据库中必不可少的工具。 Awk从第一行到最后一行逐行扫描文件(或输入),搜索与指定模式匹配的行,并在这些行上执行选定的操作(用大括号括起来)。 如果存在没有特定操作的模式,则显示所有与该模式匹配的行;否则,将显示所有行。 如果存在没有特定模式的动作,则所有输入行多会被执行。

1.1 工作原理

测试文件:names

Tom Savage 100
Molly Lee 200
John Doe 300

案例: awk ‘{print $1,$3}’ names
结果:

Tom 100
Molly 200
John 300
  1. awk 从文件或者管道获取第一行作为输入信息,将其保存到内部变量$1中;默认,每一行都会保存为一个临时记录;如下图所示:
    变量$0
  2. awk 通过空格或者tab键将该行($0)拆分为多个区域(单词),每个区域都会存放到一个单独的内部变量中,依次从$1, $2, $3 … $n存储,最多可以存储100个变量。第一行存储如下:
    $0的存储内容
  3. awk内部有一个变量FS(field separator),它用于区分不同区域,FS默认为空格-tab键,即:默认通过空格和tab键隔离不同的区域;如果需要通过其它字符来隔离不同区域|单词,也可以修改FS的值。
  4. 将$0拆分后,通过print函数输出对应的值(实际中可以根据需要对数据进行处理输出),此处直接输出第1,3两个变量。
    {print $1,$3}
    如果两个变量之间使用’,’ 则输出之间会自动产生一个空格,如果没有’,‘则输出直接相连;
    此处$1和$3之间的’,‘映射到一个特殊的内部变量OFS(output field separator ), 其默认赋值为一个空格,因此添加’,'后输出自带空格。
  5. 当awk完成改行的输出后,其将再次获取下一行,并使用上述1-4的步骤进行处理;如此循环,直到最后一行被处理完。

1.2 使用格式

awk的使用格式如下:
awk ‘pattern’ filename
awk ‘{action}’ filename
awk ‘pattern {action}’ filename

案例1.2.1:
$date>date.txt
$cat date.txt
2020年 02月 16日 星期日 22:46:25 CST
$ cat date.txt|nawk ‘{ print "Month: " $2 "\nYear: " , $1 }’
结果:

Month: 02月
Year:  2020年

案例1.2.2:
数据employees

Tom Jones       4424      5/12/66     543354
Mary Adams      5346      11/4/63     28765
Sally Chang     1654      7/22/54     650000
Billy Black     1683      9/23/44     336500

结果:

$ nawk '/Sally/{print "\t\tHave a nice day, " $1, $2 "\!"}' employeesHave a nice day, Sally Chang!

2 常用功能介绍

2.1 格式化输出

  1. print 函数
    案例2.1.1:date| awk ‘{ print "Month: " $2 "\nYear: " , $1 }’
    说明:输出月份和年

    案例2.1.2:awk ‘/Sally/{print "\t\tHave a nice day, " $1, $2 “!”}’ employees
    说明:匹配Sally开始的行,输出: Have nice day,Sally Chang

  2. OFMT变量
    OFMT变量用于控制输出的数字格式, 该功能也可以通过printf来实现.
    案例2.1.3:awk ‘BEGIN{OFMT="%.2f"; print 1.2456789, 12E-2}’
    说明:用于控制数字输出格式,小数点后2位
    结果: 1.25 0.12

  3. printf 函数
    该函数让用户可以按照指定格式对内容进行输出,类似于c语言中的printf 函数;
    其可用转化字符包括:
    |转换字符 |定义 |
    |–|--|
    | c | 字符 |
    | s | 字符串 |
    | d | 十进制 |
    | ld | 长整形十进制 |
    | u | 无符号十进制|
    | lu | 长整形无符号十进制 |
    | x | 十六进制 |
    | lx | 长十六进制 |
    | o | 八进制 |
    | lo | 长八进制 |
    | e | 使用科学计数法的浮点数 |
    | f | 浮点数 |
    | g | 浮点数,使用e后者f类型(自动占用最少空间) |
    其可用修饰器包括:
    | 字符 | 定义 |
    |–|--|
    | - | 左对齐 |
    | # | 八进制整数起始为一个0,十六进制整数起始为0x |
    | + | 对于转移字符为d,e,f,g的整数, 会显示其+或者- 符号 |
    | 0 | 显示的值填充为0,而非空格 |

    案例2.1.4 : echo “UNIX” | awk ’ {printf “|%-15s|\n”, $1}’
    说明: 输出UNIX,且左对齐占用15个字符,默认补充为空格,若无-则为右对齐;
    结果: |UNIX |

    案例2.1.5: awk ‘{printf “The name is: %-15s ID is %8d\n”, $1, $3}’ employees
    说明: 输出The name is: xx(占用15个字符,左对齐) ID is yy(占用8位切右对齐)
    结果:

    The name is: Tom             ID is     4424
    The name is: Mary            ID is     5346
    The name is: Sally           ID is     1654
    The name is: Billy           ID is     1683
    

2.2 从文件获取awk命令

将awk命令写入文件中,通过-f导入命令,然后执行;若文件中由多个处理规则|方法,则每个行数据都会被这些规则处理,然后输出.

假设存在 awkfile 文件,包含2行内容,

/^Mary/{print "Hello Mary"}
{print $1,$2,$3}

案例2.2.1 : awk -f awkfile employees
说明: 对每一行数据,先匹配是否一Mary开头,是则输出Hello Mary; 并输出第1-3个单词;
结果:

Tom Jones 4424
Hello Mary
Mary Adams 5346
Sally Chang 1654
Billy Black 1683

除此之外,若有多个 匹配模式和行为,则可以将这些内容逐行写到脚本文件中,然后通过-f导入. 脚本中可以使用#来注释不需要的内容.
假如由info脚本文件,内容如下:

# My first awk script by Jack Sprat
# Script name: info; Date: February 28, 2004
/Tom/{print  "Tom's birthday is "$3}
/Mary/{print NR, $0}
/^Sally/{print "Hi Sally. "  $1 " has a salary of  $" $4 "."}
# End of info script

第1,2,6为注释内容,3,4,5为对的awk模式和行为, NR标志当前为第几行.
案例2.2.2: awk -f info employees
说明: 对每一行,分别用3,4,5对应的规则进行匹配,匹配到则执行对应的行为.
结果:

Tom's birthday is 4424
2 Mary Adams      5346      11/4/63     28765
Hi Sally. Sally has a salary of  $7/22/54.

2.3 模式和动作

  • 模式
    awk中的模式可以为正则表达式,或者一个条件表达式, awk的每行会对使用模式进行判断,符合要求则输出.

    案例 2.3.1: awk ‘/Tom/’ employees
    说明: 匹配到Tom则输出改行,等价于 awk ‘$0 ~ /Tom/{print $0}’ employees
    结果: Tom Jones 4424 5/12/66 543354
    注意: 等价表达中~ 为匹配符, 即从$0中匹配正则表达/Tom/

    案例2.3.2: awk ‘$3 < 4 000’ employees
    说明: 匹配到$3小鱼4000的行,并输出
    结果:

    Sally Chang     1654      7/22/54     650000
    Billy Black     1683      9/23/44     336500
    
  • 动作
    awk中动作为{}包围的语句, 动作既可以由模式触发,又可以单独使用, 还可以多个动作同时使用(多个动作之间使用;隔开). 其格式为 {action}

    案例2.3.3: date | awk ‘{print $1, $2, $3}’
    说明: 输出 年 月 日

    案例2.3.4: date | awk ‘{print $1; print $2}’
    说明: 2个动作,分行输出 年 月; 等价于 date | awk ‘{print $1};{print $2}’

    案例2.3.5: awk ‘/Tom/ {print “hi tom!”}’ employees
    说明: 匹配到Tom后才执行动作,输出hi tom!

2.4 正则表达

awk的模式中支持正则表达式, 基本用法大致同grep的正则表达类似; 若某一行输入被正则匹配到,则会执行正则对应的行为; 若正则后没有对应的行为,则直接输出匹配的行.
以下为awk支持的正则标志和作用:

MetacharacterWhat it does
^从字符串起始开始匹配
$从字符串结尾开始匹配
.匹配一个字符
*匹配0或者多个之前的字符
+匹配至少1个之前的字符
?匹配0这这1个之前的字符
[ABC]匹配任何一个在集合中的字符
[ABC]匹配任何一个不在集合中的字符
[A-Z]匹配任何一个在A-Z 范围的字符
A|B匹配A或者B
(AB)+匹配至少1个集合AB例如AB,ABAB,ABABAB等
\*匹配字符 * 符号
&用于保存搜索的字符串, 多配合替换功能

注: awk 不支持: \< >/ , \( \) , \{ \} 等3种正则用法;

案例2.4.1: awk ‘/Mary/’ employees
说明: 输出包含Mary的行

案例2.4.2: awk ‘/^[A-M][a-z]+ /’ employees
说明: 匹配 以大写A-M之间字符开头,紧接着至少1个小写字母,随后一个空格 的行
结果:

Mary Adams      5346      11/4/63     28765
Billy Black     1683      9/23/44     336500

3 经典案例

  1. 文本信息打印
    打印文件的第一列(域) : awk ‘{print $1}’ filename
    打印文件的前两列(域) : awk ‘{print $1,$2}’ filename
    打印完第一列,然后打印第二列 : awk ‘{print $1 $2}’ filename
    打印文本文件的总行数 : awk ‘END{print NR}’ filename
    打印文本第一行 :awk ‘NR==1{print}’ filename
    打印文本第二行第一列 :sed -n “2, 1p” filename | awk ‘print $1’
  2. 进程信息处理
    关闭wps相关所有进程:ps -ef|grep wps|awk ‘{print $2}’|xargs kill
  3. awk练习题
    数据源 data.txt 内容如下:
     wang     4cui      3zhao     4liu      3liu      3chang    5li       2
    
    1 通过第一个域找出字符长度为4的
    2 当第二列值大于3时,创建空白文件,文件名为当前行第一个域$1 (touch $1)
    3 将文档中 liu 字符串替换为 hong
    4 求第二列的和
    5 求第二列的平均值
    6 求第二列中的最大值
    7 将第一列过滤重复后,列出每一项,每一项的出现次数,每一项的大小总和
    1、字符串长度
    awk ‘length($1)==“4”{print $1}’
    2、执行系统命令
    awk ‘{if($2>3){system ("touch "$1)}}’
    3、gsub(/r/,“s”,域) 在指定域(默认$0)中用s替代r (sed ‘s///g’)
    awk ‘{gsub(/liu/,“hong”,$1);print $0}’ a.txt
    4、列求和
    df -h | awk ‘{a+=$2}END{print a}’
    5、列求平均值
    df -h | awk ‘{a+=$2}END{print a/NR}’
    df -h | awk ‘{a+=$2;b++}END{print a,a/b}’
    6、列求最大值
    df -h | awk ‘BEGIN{a=0}{if($2>a) a=$2 }END{print a}’
    7、将第一列过滤重复列出每一项,每一项的出现次数,每一项的大小总和
    awk ‘{a[$1]++;b[$1]+=$2}END{for(i in a){print i,a[i],b[i]}}’
  4. 使用特定区域分隔符
    案例: cho ‘Tom Jones:4424:5/12/66:543354’|awk -F: ‘/Tom Jones/{print $1,$2}’
    结果: Tom Jones 4424
    说明: -F: 制定分隔符为:, 默认为空格或者tab符.
  5. 匹配操作符(~)
    匹配操作符号~, 其作用为: 让一个正则从一条记录或者一个区域中进行匹配.
    案例: awk ‘$1 ~ /[Bb]ill/’ employees
    说明: 说明, 匹配第一个区域, 包括Bill或者bill , 注意$1 表示只用$1 进行匹配,若该为$0 这用一条记录进行匹配.
    结果: Billy Black 1683 9/23/44 336500

4 注意事项

  1. 后续将在此处增加awk使用中常见的注意事项

5 说明

测试系统版本:Ubuntu 1910 SERVER (64-bit)
参考文献: UNIX® Shells by Example Fourth Edition By Ellie Quigley

这篇关于Ubuntu小技巧15--awk命令详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1017133

相关文章

【EverEdit】活用 EverEdit 小技巧

【EverEdit】活用 EverEdit 小技巧 (1)设置 EverEdit 对比文件文本内容 设置如下图所示: 首先要先打开要对比的文本文件,和对比文件相比,此时打开了至少两个文件: 选择文件比较: (2)如何设置 EverEdit 监视文件的变化 设置如下图所示:

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

Jitter Injection详解

一、定义与作用 Jitter Injection,即抖动注入,是一种在通信系统中人为地添加抖动的技术。该技术通过在发送端对数据包进行延迟和抖动调整,以实现对整个通信系统的时延和抖动的控制。其主要作用包括: 改善传输质量:通过调整数据包的时延和抖动,可以有效地降低误码率,提高数据传输的可靠性。均衡网络负载:通过对不同的数据流进行不同程度的抖动注入,可以实现网络资源的合理分配,提高整体传输效率。增

Steam邮件推送内容有哪些?配置教程详解!

Steam邮件推送功能是否安全?如何个性化邮件推送内容? Steam作为全球最大的数字游戏分发平台之一,不仅提供了海量的游戏资源,还通过邮件推送为用户提供最新的游戏信息、促销活动和个性化推荐。AokSend将详细介绍Steam邮件推送的主要内容。 Steam邮件推送:促销优惠 每当平台举办大型促销活动,如夏季促销、冬季促销、黑色星期五等,用户都会收到邮件通知。这些邮件详细列出了打折游戏、

探索Elastic Search:强大的开源搜索引擎,详解及使用

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引入 全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选,相信大家多多少少的都听说过它。它可以快速地储存、搜索和分析海量数据。就连维基百科、Stack Overflow、

邮件群发推送的方法技巧?有哪些注意事项?

邮件群发推送的策略如何实现?邮件推送怎么评估效果? 电子邮件营销是现代企业进行推广和沟通的重要工具。有效的邮件群发推送不仅能提高客户参与度,还能促进销售增长。AokSend将探讨一些关键的邮件群发推送方法和技巧,以帮助企业优化其邮件营销策略。 邮件群发推送:目标受众 了解他们的需求、兴趣和行为习惯有助于你设计出更具吸引力和相关性的邮件内容。通过收集和分析数据,创建详细的客户画像,可以更精

Linux 下的Vim命令宝贝

vim 命令详解(转自:https://www.cnblogs.com/usergaojie/p/4583796.html) vi: Visual Interface 可视化接口 vim: VI iMproved VI增强版 全屏编辑器,模式化编辑器 vim模式: 编辑模式(命令模式)输入模式末行模式 模式转换: 编辑-->输入: i: 在当前光标所在字符的前面,转为输入模式

常用MQ消息中间件Kafka、ZeroMQ和RabbitMQ对比及RabbitMQ详解

1、概述   在现代的分布式系统和实时数据处理领域,消息中间件扮演着关键的角色,用于解决应用程序之间的通信和数据传递的挑战。在众多的消息中间件解决方案中,Kafka、ZeroMQ和RabbitMQ 是备受关注和广泛应用的代表性系统。它们各自具有独特的特点和优势,适用于不同的应用场景和需求。   Kafka 是一个高性能、可扩展的分布式消息队列系统,被设计用于处理大规模的数据流和实时数据传输。它