Linux文本处理命令


正则表达式

POSIX标准将正则表达式分为两类
1.基本的正则表达式
2.扩展的正则表达式
大部分Linux应用和工具仅支持基本的正则表达式

基本正则表达式

符号 意义
* 0个或多个字符
. 匹配任意字符
^ 行首,在[]中表示非
$ 行尾
[] 匹配字符集合
\ 转义字符
\<\> 精确匹配符号
\{n\} 匹配n次
\{n,\} 匹配至少n次
\{m,n\} 匹配m~n次

扩展正则表达式

符号 意义
? 匹配0个或1个
+ 匹配1个或多个
() 表示一个字符集合或用在expr中
| 表示或

通配符

bash Shell本身不支持正则表达式,使用正则表达式的是shell命令和工具,如grep,AWK,sed等。但是bash Shell可以使用正则表达式中的一些元字符实现通配。

符号 意义 示例 解释
* 任意字符 Phi*ip.rtf 以Phi开头,以ip.rtf结尾的文件
? 一个任意字符 ls -l 0?.pem 列出0开头且文件为两个字符的pem文件
[] 表示范围 ls -l [a-h].awk 列出以a-h开头的awk文件
{} 一组表达式的组合 ls -l {[a-h]*.awk,0?.pem} 匹配[a-h]*.awk或0?.pem的文件
^ 取反 ls -l [a-h]*.[^awk]* 以a-h开头,且不是awk类型的文件

Grep

全面搜索正则表达式并把行打印出来(Global search Regular Expression and Print out the line)
grep [选项][模式][文件…]

选项

选项 意义 整词
-c 只输出匹配行的数量 count
-i 搜索时忽略大小写 ignore
-h 查询多文件时不显示文件名  
-l 只列出符合匹配的文件名,而不列出具体的匹配行 list
-n 列出所有的匹配行,并显示行号 number
-s 不显示不存在或无匹配文本的错误信息  
-v 显示不包含匹配文本的所有行 reverse
-w 匹配整词 word
-x 匹配整行  
-r 递归搜索,不仅搜索当前工作目录,而且搜索子目录 recursion
-q 禁止输出任何结果,以退出状态表示搜索是否成功 quit
-b 打印匹配行距文件头部的偏移量,以字节为单位 byte
-o 与-b选项结合使用,打印匹配的词距文件头部的偏移量,以字节为单位  
-E 支持扩展的正则表达式 Extract
-F 不支持正则表达式,按照字符串的字面意思进行匹配  

模式

字符串、变量、正则表达式

注意:只要模式中包含空格,就需要使用双引号将模式引进来

实例

-w和-x选项
grep命令模式支持正则表达式,正则表达式的元字符被解释成特殊含义;
-w选项表示匹配整词,即以模式的字面含义去解释
如:
grep cer* *.pem
grep -w cer* *.pem
-x 是匹配整行
-w 使用不方便,最好和 -F 一起使用

grep命令族

grep
标准grep命令,支持基本正则表达式 egrep
扩展grep命令,支持基本和扩展正则表达式
等价于grep -E fgrep
快速grep命令,不支持正则表达式,按照字面意思进行匹配
等价于grep -F

sed

sed,stream editor,流编辑器,将一系列编辑命令作用于一批文本文件
适用场合:

编辑相对交互式编辑器而言太大的文件 编辑命令太复杂,在交互式文本编辑器中难以输入的情况 对文件扫描一遍,但是需要执行多个编辑函数的情况

三种调用方式

sed [选项] ‘sed命令’ 输入文件 sed [选项] -f sed脚本 输入文件 ./sed脚本文件 输入文件

选项

选项 意义
-n 不打印所有行到标准输出
-f 表示正在调用sed脚本文件
-e 表示将下一个字符串解析为sed编辑命令,如果只传递一个编辑命令给sed,可以省略-e

sed命令

通常由定位文本行和sed编辑命令两部分组成,sed编辑命令对定位文本行进行各种处理

sed定位文本行

选项 意义
x x为指定行
x,y 指定行范围
/pattern/ 包含模式的行
/pattern/pattern/ 包含两个模式的行
/pattern/,x 从与pattern的匹配行到x之间的行
x,/pattern/ 从x开始到pattern的匹配行
x,y! 不包括x和y的行

sed编辑命令

sed编辑命令标示对文本进行何种处理,如打印,删除,追加,插入,替换等

选项 意义
p 打印匹配行
= 打印文件行号
d 删除定位行
a\ 在定位行号之后追加文本
i\ 在定位行号之前插入文本
c\ 用新文本替换定位文本行
s 使用替换模式替换相应模式
r 从另一个文件中读文本
w 将文本写入另一个文本
y 变换字符
q 第一个模式匹配完成后退出
l 显示与八进制ASCII码等价的控制字符
{} 在定位行执行的命令组
n 读取下一个输入行,用下一个命令处理新的行
h 将模式缓冲区的文本复制到保持缓冲区
H 将模式缓冲区的文本追加到保持缓冲区
x 交换模式缓冲区和保持缓冲区
g 将保持缓冲区文本复制到模式缓冲区
G 将保持缓冲区文本追加到模式缓冲区

实例

sed -n ‘1p’ file sed -e ‘/^f*/p’ -e ‘/^f*/=’ file 定位命令
匹配元字符
sed -n ‘/./p’ input
sed -n ‘/$/p’ input 使用元字符进行匹配
sed -n ‘p′input(注意:在sed命令中表示最后一行)
sed -n ‘/^$/p’ input (匹配空行)
sed -n ‘/.*bus/p’ input !符号
sed -n ‘2,10!p’ input 使用行号与关键字匹配限定行范围
sed -n ‘/seugrid/,$p’ input
sed -n ‘3,/seugrid/p’ input

编辑命令

插入文本
sed ‘指定地址i\text’ input (在指定位置之前插入)
sed ‘指定地址a\text’ input (在指定位置之后插入)
sed ‘/i/i\input\nsecond’ (插入两行input和second)
sed ‘/i/a\input\nsecond’ 修改文本
sed ‘指定地址c\text’ input (将整个匹配行修改为新文本行)
sed ‘/Certificate/c\New line:’ input 删除文本
sed ‘指定位置d’ input (删除指定行) 替换文本
sed ‘s/被替换字符串/新字符串/[替换选项]’
sed ‘s/被替换字符串/新字符串/number[替换选项]’(表示第number(1~512)次匹配)
选项 意义
g 全部替换
p 与-n选项结合,只打印替换行
w 文件名 表示将输出定向到一个文件
写入新文件
sed ‘指定地址w file’ input
sed ‘1,5w file’ input
sed ‘/Certificate/w file’ input 从文件读入文本
sed ‘指定地址r file’ input 退出命令
sed ‘指定地址q’ input 变换命令
sed ‘y/被替换字符序列/变换的字符序列/’ 输入文件
两个序列长度必须一样
sed ‘y/fmg/FMG/’ input 显示控制字符
显示退格符,F1键,shift键等
sed -n l input
sed -n ‘指定位置l’ input 在定位行执行命令组
sed -n -e ‘/Certificate/p’ -e ‘/Certificate/=’ input
sed -n ‘/Certificate/{p;=}’ input 高级编辑命令
处理匹配行的下一行
sed ‘/Certificate/{n;s/11/99/;}’ input sed缓冲区的处理
sed ‘/Subject/h;/seugrid/x;$G’ input
1.匹配Subject,并将匹配行写入保持缓冲区
2.匹配seugrid,将保持缓冲区和模式缓冲区交换
3.到结尾行,将保持缓冲区追加到模式缓冲区 利用分号分隔多个编辑命令
上例已经使用了这种表示

AWK

awk的基本语法与C语言类似,与sed的功能类似,用来处理文本,awk可以从文件或字符串中基于指定规则浏览和抽取信息,在抽取信息的基础上,才能进行其他文本操作
最新的awk是gawk,可以实现数据查找,抽取文件中数据,创建管道流命令

AWK编程模型

awk程序由一个主输入循环维持,主输入循环自动依次读取文件行,用程序员定义的处理文件行的动作处理,循环执行直到终止条件。
与C,C++,Java的不同是,程序员不需要关注打开文件,读取文件行,关闭文件的动作,而只关注处理行的执行动作。

AWK框架

AWK调用

Shell中调用
awk [-F 域分隔符] ‘awk程序段’ 输入文件 将awk程序段插入脚本文件
awk -f awk脚本文件 输入文件 将脚本文件设置为可执行
./awk脚本文件 输入文件

AWK编程

AWK模式匹配

awk由模式和动作组成。模式是一组用于测试输入行是否需要执行语句,动作则是包含语句,函数和表达式的执行过程。即模式决定动作何时触发事件,动作执行对输入行处理
如:awk ‘/^$/{print “this is a blank line.”}’ input

记录和域

awk认为文件是有结构的,每一行为一个记录,记录由域组成,域之间使用空格,Tab或其他符号进行分隔。
域操作符$:指定执行动作的域,$1…标识每一个域,$0表示整个记录;也可以跟变量或变量表达式
如:awk ‘BEGIN{one=1;two=2} {print $(one+two)}’ input
默认是空格,Tab键被认为是多个空格(也多个空格被当成一个空格)
1.可以使用-F 来改变默认的分隔符
2.可以使用环境变量FS设置分隔符
实例:
1.FS=”\t”
2.FS=”\t+”
记录:waz\t\tcq
对于FS=”\t” 分成三个域,waz,空域,cq;对于FS=”\t+”,结果是waz,cq

关系和布尔运算符

运算符 意义
<  
>  
~ 匹配正则表达式
!~ 不匹配正则表达式
ll  
&&  
!  
实例:测试~运算符
awk ‘BEGIN{FS=”:”} $1~/root/’ input awk 条件语句
与C类似,有if,if/else,if/else if/else
awk ‘BEGIM{FS=”:”}{if(1 /root/)print0}’ passwd

表达式

支持加(+),减(-),乘(*),除(/),模(%),乘方(^或**),自增(++x,x++)
一个表达式可由数值,字符常量,变量,操作符,函数和正则表达式

实例

1.统计空白行数
awk ‘/^$/{x+=1}END{print x}’ input
2.计算平均成绩
awk ‘BEGIN{FS=”,”}{total=4+5+6+7;avg=total/4;print $1,avg}’ input

系统变量

变量 意义
$n 当前记录的第n个域,域间由FS分隔
$0 记录的所有域
FS 字段分隔符,默认空格
RS 记录分隔符,默认换行
NR 当前记录数
NF 当前记录中的域数量
OFS 输出域分隔符,默认空格
ORS 输出记录分隔符,默认换行
FILENAME 当前文件名
ARCC 命令行参数的数量
ARGIND 命令行中当前文件的位置(从0开始标号)
ARGV 命令行参数数组
CONVEMT 数字转换格式
ENVIRON 环境变量关联数组
ERRNO 最后一个系统错误的描述
FILEDWIDTHS 字段宽度列表,以空格键分隔
FIR 浏览文件的记录数
IGNORECASE 布尔变量,如果为真,则进行忽略大小写的匹配
OFMT 数字的输出格式
RLENGTH 由match函数匹配的字符串长度
RSTART 由match函数所匹配的字符串的第一个位置
SUBSEP 数组下标分隔符,默认值是\034

格式化输出

awk的一大功能是产生报表,报表就需要按照预定的格式化输出
printf(格式控制符,参数)

修饰符 意义
- 左对齐
width 域的步长
.prec 小数点右边的位数
0 1 2 3 4 5 6 7
格式符 %c %d %e %f %o %x %s

内置字符串函数

函数名 意义
gsub(r,s) 在输入文件中用s替换r,作用域为$0
gsub(r,s,t) 在t中用s替换r,可以作用于某个域$n
index(s,t) 返回s中字符串第一个t的位置
length(s) 返回s的长度
match(s,t) 测试s是否包含匹配t的字符串
split(r,s,t) 用t分隔r,生成数组s,生成数组的元素个数
sub(r,s,t) 将t中第一次出现的r替换为s
substr(r,s) 返回字符串r中从s开始的后缀部分
substr(r,s,t) 返回字符串r中从s开始长度为t的后缀部分
实例
awk ‘BEGIN{FS=”:”;OFS=”:”} gsub(/root/,”gridsphere”,$1)’ input awk ‘BEGIN{FS=”:”;OFS=”:”} gsub(/root/,”gridsphere”){print $0}’ input awk ‘BEGIN{print index(“gridsphere”,”ph”)}’ awk ‘BEGIN{print length(“gridsphere”)}’ awk ‘BEGIN{print match(“hello”,/h.*/)}’

向awk脚本传递参数

awk脚本内的变量可以在命令行中进行赋值,实现awk脚本传递参数,变量赋值放在脚本之后、输入文件之前,如
awk脚本 parameter=value 输入文件
awk传递的参数可以是自定义的,也可以是系统变量

条件语句和循环语句

if() 动作1 [else 动作2]
while() 动作
do 动作 while()
for()动作

数组

array[index]=value
1.关联数组
关联数组是指数组的索引可以是字符串,也可以是数字
关联数组的值无须以连续的地址进行存储。
awk的所有数组都是关联数组。使用的数字索引并不代表数组存储地址信息
访问数组:
for(variable in array) do something with array[variable]
判断数组中是否存在某元素
if(index in array) do
2.split函数
split(r,s,t):以t为分隔符,将r字符串拆分为字符串数组,并存放在s中
awk ‘BEGIN{print split(“abc/def/ghi”,str,”/”);for(i in str) print str[i]}’

文本处理命令

文本处理命令包含对文件记录的排序、文件的合并和分隔等。具体命令:sort,uniq,join,cut,paste,split,tr,tar。这些命令实现了对文件记录排序,统计,合并,提取,粘贴,分隔,过滤,压缩和解压等功能。与sed,awk构成了Linux文本处理的所有命令和工具

sort

rt:对文件进行排序。将输入文件看做由多条记录组成的数据流,而记录由可变宽度的字段组成。,以换行符作为定界符,sort命令与awk一样,可将记录分成多个域进行处理,默认的域分隔符是空格符

sort [选项] [输入文件]

选项 意义
-c 测试文件是否已经被排序
-k 指定排序的域
-m 合并两个已排序的文件
-n 根据数字大小进行排序
-o[输出文件] 将输出写入到指定的文件,相当于将输出重定向到指定文件
-r 将排序结果逆向显示
-t 改变域分隔符
-u 去除结果中的重复行
sort -t: input sort -t: -k3 input sort -t: -k3n input
-n一般不单独使用,一般放在域号之后 sort -t: -k3nr input sort -t: -u input sort -t: -k3n -o output input sort -t: -c input sort -t: -m input1 input2
input1和input2必须有序

uniq

用于去除文本文件中的连续的重复行,类似sort -u

选项 意义
-c 只打印每行在文本中重复出现的次数
-d 只显示有重复的记录,每个重复记录只出现一次
-u 只显示没有重复的记录

统计文件中的单词数
cat input | sed ‘s/./ /g;s/=/ /g;s/,/ /g;s/\// /g;s/ /\n/g;s/\t/\n/g’| sed ‘/^$/d’|sort| uniq -c | sort -nr

join

连接操作将两个文件中具有相同域的记录选择出来,再将这些记录所有的域放到一行(包含来自两个文件的所有域)
注意:文件必须有序

选项 意义
-a1或-a2 除了显示以共同域进行连接的结果外,-a1表示还显示第一个文件中没有共同域的记录,-a2则表示显示第二个文件中没有共同域的记录
-i 比较域内容时,忽略大小写差异
-o 设置结果显示的格式
-t 改变域分隔符
-v1或-v2 与-a类似,但是,不显示以共同域进行连接的结果
-1和-2 -1用于设置文件1用于连接的域,-2用于设置文件2用于连接的域

join [选项] file1 file2
有点像sql中的join

join -t: teacher.db teacher_hobby.db
默认第一个域比较,相等就连接。 -a有点像左外连接,右外连接
-a1 左连接 -a2右连接 -o表示显示那些域(sql中的字段)
表示方式为 -o1.n 2.n -i忽略大小写 -t设置域分隔符 -v取反,即不显示共同域
用法与-a类似,-v1 -v2 -1,-2表示用来连接的域

实例

对于多个域的连接,使用awk

awk ’
//(NR表示读取的记录数,FNR表示在当前文件中的记录数,只有第一个文件才能使得NR\==FNR)
NR==FNR
{
a[$1 FS $2]=$0;
//相当于break,本行处理结束,处理下一行
next;
}
//最终执行到这里时,a中存储的是文件1中的记录
//当文件2的$1 FS $2在a中说明两个文件这两行一样
$1 FS$2 in a
{
//将指定列相等的记录存储在b中
b[FNR]=a[$1 FS $2] FS $3
}
END
{
//打印
//awk中的数组是关联数组
for(i=1;i<=FNR;i++)
if(i in b)
print b[i]
}’
test1 test2

cut

cut命令用于从标准输入或文本文件中按域或按行提取文本

选项 意义
-c 指定提取的字符数或字符范围
-f 指定提取的域数或域范围
-d 改变域分隔符
-c按字符提取文本
cut -c2 input
cut -c1,5 input(提取第1个和第5个字符)
cut -c1-5 input(提取1~5这五个字符) -f按域提取文本 -d类似sort和join中的-t

paste

用于将文本文件或标准输出中的内容粘贴到新的文件,它可以将来自不同文件的数据粘贴到一起,形成新的文件。如果两个文件的行数不同,少的那个为空

paste [选项] 文件1 文件2…

选项 意义
-d 默认域分隔符是空格或Tab键,设置新的域分隔符
-s 将每个文件粘贴成一行
- 从标准输入中读取数据

split

用于将大文件切割成小文件,split命令可以按照文件的行数,字节数切割文件,并能在输出的多个文件中自动加上编号

split [选项] 待切割的大文件 输出的小文件

选项 意义
-n 用于指定切割成小文件的行数
-b 指定切割成小文件的字节
-C 与-b类似,但是,切割时尽量维持每行的完成性
split -2 input input(默认是x) split -b100 input input split -C100 input input

tr

现字符转换功能,tr能完成的sed都能完成,但是tr简单

tr [选项] 字符串1 字符串2 < 输入文件

选项 意义
-c 反选字符串1的字符集
-d 删除字符串1中出现的所有字符
-s 删除所有重复出现的字符序列,只保留一个

tar

归档命令,实现了打包和解压文件

tar [选项] 文件名或目录名

选项 意义
-c 创建新的包
-x 解压文件
-t 列出包内容
-f 使用压缩文件或设备,该选项通常是必须的
-z 用gzip压缩和解压缩文件,若加上此选项创建压缩包,那么解压缩时也需要加上此选项
-j bz2
-v 查看过程
-r 向宝中添加文件

gzip 压缩文件

Linux文本处理总结

Linux文本处理命令 应用
grep 全面搜索正则表达式并把行打印出来,grep命令族:grep,egrep,fgrep
sed 流编辑,将一系列编辑命令作用于缓冲区中输入文件的副本,从而实现输入文件的各种编辑操作
awk 特点是处理结构化文件,所谓结构化,指划分为域和记录的文件
sort 对文本进行排序
uniq 去除文本的连续重复行,也可以统计重复行的数量
join 类似数据库中的连接操作
cut 从标准输入或输入文件中按行或按域提取文本
paste 用于将多个文件或标准输出中的内容粘贴而形成新的文件
split 用于将大文件切割成小文件
tr 实现字符替换功能,可以实现文本文件的过滤功能
tar 归档命令,和gzip用于实现Linux系统文件的压缩和解压

 

相关内容