Shell程序设计 | 文本处理工具 :正则表达式、grep、sed、awk
文章目录
- 正则表达式
- grep
- sed
- awk
- 其它常用工具
- cut
- sort
- uniq
- tr
- 常见面试题
- 第十行
- 有效电话号码
- 统计词频
- 转置文件
要想使用这些流式处理工具,那么就必须得了解正则表达式,由于正则表达式内容较多,一篇博客肯定写不完,所以这里只是简单的讲一下正则表达式的常用语法。
正则表达式
元字符
选项 | 说明 |
---|---|
\ | 转义字符 |
. | 匹配任意一个字符 |
* | 匹配其前面的字符0次或者n次 |
^ | 匹配开头 |
$ | 匹配结尾 |
[a-z] | 匹配方括号中的任意一个字符 |
拓展元字符
选项 | 说明 |
---|---|
+ | 匹配前面的正则表达式至少一次 |
? | 匹配前面的正则表达式,出现0次或者一次 |
将这些元字符搭配起来,就成为了正则表达式,在下面几个工具的用例中会进行具体演示
下面介绍Linux中流式文本处理的三剑客——文本过滤工具grep、文本编辑工具sed、文本报告生成器awk
grep
grep是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。它也是我们在linux中最常用到的工具之一
语法
grep [选项](查询内容)(参数)
常用选项
-i:忽略大小写
-r:递归读取一个目录下所有文件
-E:支持拓展正则表达式
sed
sed是一种强大的文本编辑工具。它一次处理一行内容,处理时把当前处理行存储在临时缓冲区中(模式空间)中,接着使用sed命令处理缓冲区中的内容,把处理完的数据送往终端,接着输出下一行数据,直至文件末尾
语法
sed [选项] '命令' (参数)
常用选项
-e:直接在指令列模式上进行sed的动作编辑,即可以使用多次命令
-n:只输出匹配行(也可以指定修改行)
-r:支持使用扩展正则表达式
常用命令
a:追加,在下一行出现
i:插入,在上一行出现
d:删除
s:查找并替换
p:打印当前模式空间内容
使用示范,以下列文本分别进行增删改
hello
world
this
is
test
file
aaaaa
bbbbbbb
cccccccccc
123123124
world
hello
在以t开头的行的下一行追加xxxxxxxxx
cat test3 | sed '/^t/axxxxxxxxx'
删除所有以d结尾的行
cat test3 | sed '/d$/d'
将文本中的所有b替换为d
cat test3 | sed 's/b/d/g'
awk
awk一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
其实awk是是一门用于处理文本文件的编程语言,而gawk是这门编程语言的具体实现,因此其支持和shell类似的算术运算、条件判断、流程控制等语法。
下面是man手册中awk的说明,当我们查询awk的时候就会自动跳转至gawk
语法
awk [选项] ‘匹配模式1{执行操作1} 匹配模式2{执行操作2}......’ (参数)
注意:只有匹配了pattern的行才会执行action
同时也可以指定开头和结尾执行的内容
awk [选项] ‘BEGIN{开始时执行的内容} 匹配模式1{执行操作1} END{结束时执行的内容}’ (参数)
注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。
常用选项
-F<分隔字符>:指定输入文件折分隔符
-v:赋值一个用户定义变量
常用系统变量
FILENAME:文件名
NR:已读的记录数(即当前的行数)
NF:浏览记录的域的个数(切割后,列的个数)
由于awk数组、运算、条件判断、流程控制、函数等内容与shell和c语言高度类似,这里就不多花篇幅介绍了
使用示范:切割出ifconfig中ens38的ip地址
ens38: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.220.128 netmask 255.255.255.0 broadcast 192.168.220.255inet6 fe80::8e00:5dc0:711b:a9cf prefixlen 64 scopeid 0x20<link>ether 00:0c:29:4e:dd:e4 txqueuelen 1000 (Ethernet)RX packets 1513042 bytes 952654297 (908.5 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 1444185 bytes 1229233776 (1.1 GiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 1000 (Local Loopback)RX packets 185821127 bytes 25600956325 (23.8 GiB)RX errors 0 dropped 5322 overruns 0 frame 0TX packets 185821127 bytes 25600956325 (23.8 GiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ifconfig ens38 | grep inet\ | awk -F " " '{print$2}'
使用示范:查找出文本中的空行
the day is sunny the thethe sunny is is
awk '/^$/{print NR}' words
其它常用工具
以下是其他常用的工具,由于用法简单,所以这里就简单介绍一下
cut
cut的主要功能就是剪切数据
语法
cut [选项](参数)
常用选项
-f:列号,提取第几列
-d<分隔字符>:分隔符,按照指定分隔符分割列
使用示范:获取文本中的姓名
name age
alice 21
ryan 30
cat test | cut -d ' ' -f 1
sort
sort用于对文本内容进行排序
语法
sort [选项](参数)
常用选项
-t<分隔字符>:指定排序时所用的栏位分隔字符
-n:依照数值的大小排序
-r:以相反的顺序来排序
-k:指定需要排序的列
使用示范:对文本中的数据进行排序
123123
42
647
453
6789
23
1
457
97312
cat nums | sort -n
uniq
uniq命令用于对数据流进行去重,通常与sort搭配使用
语法
uniq [选项](参数)
常用参数
-c:在每列旁边显示该行重复出现的次数;
-d:仅显示重复出现的行列;
使用示范:统计文本中每个单词出现的次数
the
day
is
sunny
the
the
the
sunny
is
is
先去重,根据重复的次数进行排序
cat test2 | uniq -c | sort -n
tr
tr用于对文本内容进行修改、替换、压缩
语法
tr [选项](参数)
常用参数
-d:删除所有属于第一字符集的字符;
-s:把连续重复的字符以单独一个字符表示
使用示范:将小写转换为大写
the day is sunny the the
the sunny is is
cat words | tr 'a-z' 'A-Z'
常见面试题
以下题目来源于leetcode
第十行
leetcode-195. 第十行
给定一个文本文件 file.txt,请只打印这个文件中的第十行。
示例:
假设 file.txt 有如下内容:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10
你的脚本应当显示第十行:
Line 10
说明:
- 如果文件少于十行,你应当输出什么?
- 至少有三种不同的解法,请尝试尽可能多的方法来解题。
答案:
解法1:sed -n '10p' file.txt
解法2:awk 'NR==10{print $0}' file.txt
解法3:tail -n +10 file.txt | head -n 1
解题思路:
- 解法1的思路即使用sed的-n选项来只显示匹配行,然后用p命令来输出第十行
- 解法2的思路是使用awk中的系统变量NR来指定行号
- 解法3的思路是首先用tail -n +10(+为指定开始的行号)选项来获取从第十行开始的内容,接着使用head -n 1进行过滤,即只留下第一条数据,也就是第十行的内容
有效电话号码
leetcode-193. 有效电话号码
给定一个包含电话号码列表(一行一个电话号码)的文本文件 file.txt,写一个 bash 脚本输出所有有效的电话号码。
你可以假设一个有效的电话号码必须满足以下两种格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一个数字)
你也可以假设每行前后没有多余的空格字符。
示例:
假设 file.txt 内容如下:
987-123-4567
123 456 7890
(123) 456-7890
你的脚本应当输出下列有效的电话号码:
987-123-4567
(123) 456-7890
答案:
awk '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/' file.txt
解题思路:
- 直接使用awk用正则表达式进行匹配即可
统计词频
leetcode-192. 统计词频
写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率。
为了简单起见,你可以假设:
words.txt只包括小写字母和 ’ ’ 。
每个单词只由小写字母组成。
单词间由一个或多个空格字符分隔
示例:
the day is sunny the the
the sunny is is
你的脚本应当输出(以词频降序排列):
the 4
is 3
sunny 2
day 1
答案:
cat words.txt | tr -s ' ' '\n' | sort | uniq -c | sort -nr | awk '{print $2,$1}'
解题思路:
- 由于每个单词以空格为间隔,而结果是按行统计,所以使用tr命令将空格替换为换行符,使得每个单词一行
- 我们需要对出现次数进行统计,所以先使用sort对数据进行排序,使得相邻的靠在一起,然后使用uniq进行排序,并用-c选项统计出重复的次数
- 使用sort -nr,利用重复次数进行降序排序
- 使用awk对文本进行处理,将单词放在前面,次数放在后面
转置文件
leetcode-194. 转置文件
给定一个文件 file.txt,转置它的内容。
你可以假设每行列数相同,并且每个字段由 ’ ’ 分隔.
示例:
假设 file.txt 文件内容如下:
name age
alice 21
ryan 30
应当输出:
name alice ryan
age 21 30
答案:
awk '{for (i=1; i<=NF; i++){if (NR==1) {res[i]=$i}else{res[i]=res[i]" "$i}}
}
END{ for(j=1; j<=NF; j++){print res[j]}
}' file.txt
解题思路:
- 由题意可得,我们需要将行和列反转过来,所以我们需要一个数组来保存每行的字符串
- 当行号为1时,说明列号为i个单词就是第i行的开头
- 当行号不为1时,将列号为i个单词追加到数组第i项中,也就是反转后的第i行
- 需要注意的是,由于awk是按行读取的,所以我们只需要一层循环来处理每一列即可
Shell程序设计 | 文本处理工具 :正则表达式、grep、sed、awk相关推荐
- 正则表达式与扩展正则表达式(grep, sed, awk)
Linux中用来在文件中搜索字符串的命令,如grep, sed, awk等命令支持正则表达式与扩展正则表达式. 1. 基础正则表达式 符号 解释 示例 * 匹配0次或多次 b.*t . 匹配任意字符 ...
- 正则表达式grep sed awk总结
1.grep命令总结 [root@cacti ~]# cat zh888.txt //查看zh888.txt内容 123 456 abc def def [root@cacti ~]# grep - ...
- Shell ❀ 三剑客 - Grep + Sed + Awk
文章目录 八.三剑客 - Grep + Sed + Awk 1.Grep - 过滤 1.1 常用grep参数 1.2 使用方法 2.Sed - 行匹配 2.1 执行原理 2.2 常见语法 2.3 使用 ...
- 文本处理工具之grep和egrep
文本处理工具之grep和egrep grep全称global search regular expression (RE) and print out the line 正则表达式(一类字符所书写的模 ...
- linux grep sed awk
linux 文本编辑命令grep sed awk(转) grep grep (global search regular expression(RE) and print out the li ...
- linux 三剑客命令(grep,sed ,awk)
grep 命令 :强大的文本'搜索'工具 1.grep -n 'word' file_name 在file_name文件中找到word所在的所有行并显示.-n 为显示行号. 2.grep 'w[ea] ...
- linux三剑客及正则表达(grep,sed,awk)
首先我们现在知道Linux下一切皆文件,对Linux的操作就是对文件的处理,那么怎么能更好的处理文件呢?这就要用到我们上面的三剑客命令. 在说这三个命令前我们要插入一个小插曲就是"正则表达式 ...
- 三剑客grep sed awk
三剑客 正则(RE)表达式 应用场景 规则 注意事项 正则符号 基础正则 扩展正则 正则实例 正则 VS 通配符 三剑客 grep sed sed核心应用 awk awk执行过程 内置变量 awk 正 ...
- Linux高级专题详解--shell编程大全(shell变量,if语句,case语句,for循环,while循环,函数调用,数组,正则表达式,shell脚本三剑客--grep,sed,awk家族)
shell编程 初始shell 程序 语言 编程 ---------------------------------- 语言 自然语言:汉语.英语 计算机语言:c语言.c++.(java php py ...
最新文章
- java老师拿钥匙,从Java中的NavigableMap获取第一把钥匙
- 报错笔记:linux 命令行中的print输出内容无法重定向到文件中
- 使用 gRPCurl 调试.NET 5的gPRC服务
- 数字信号 fft c源码_如何制作一个简单的人体动态识别微信小程序(附源码)
- 更改tomcat的根目录路径
- 提款机转账多久到账?
- ios 7.1.2 拍照声音
- php mysql pdo出错_PHP / MySQL / PDO – 结果为false但没有DB错误消...
- html展开显示样式,html a title 自定义样式显示
- 自主招生计算机网测,自主招生考试中,笔试和机试有什么区别?
- 常见拓展名--的含义(扩宽知识面)
- class CText{}; CText t; int const CText::*p; 什么意思?
- 【github】论怎么去写一个高大上的ReadMe
- 解决pip Could not fetch URL There was a problem confirming the ssl certificate: HTTPSConnectionPool问题
- 河南省软考报名时间成绩查询河南省教育考试院河南省人事考试网报名入口
- 「JCVI」如何筛选得到最优blast比对结果?
- gentoo zen_Zen程序员的10条规则
- TM4C123GXL驱动安装
- 宽和窄俯卧撑哪个更难_宽距俯卧撑与窄距俯卧撑,练出来的肌肉有什么差距?...
- iis 自动重启的bat
热门文章
- spring项目搭建-导包对象准备
- 单例设计模式-饿汉式
- java 怎么清除画布_HTML5 Canvas 清除画布
- linux相关函数,linux学习-信号相关函数
- java 技术点_Java的21个技术点和知识点归纳
- 5.7.22mysql charset_Mysql5.7.22 坑爹的 `character_set_database`
- python unitest框架_python单元测试框架Unitest
- 全国首家工资总额负面清单管理试点企业获批
- Keras Data augmentation(数据扩充)
- 前端MVC Vue2学习总结(四)——条件渲染、列表渲染、事件处理器