简介
文本三剑客:grep、sed和awk。
它们在Linux做文本处理非常强大,如文本的匹配、过滤和替换。
grep
grep主要做的是字符串的匹配和过滤。
grep匹配规则
按行匹配。
从第一行匹配到最后一行。
只将匹配的行输出。
grep不改变文件内容。
示例
grep "root" /etc/passwd #匹配字符串"root"
输出:
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
通常我们会结合管道符使用,方便做连续过滤:
cat /etc/passwd | grep "root" | grep "bash" #查询可以登录的root用户
grep的参数
-v #不匹配此项
示例:
cat /etc/selinux/config | grep -v "^#" | grep -v "^$" #不输出空行和注释行
-A 2 #不仅输出匹配行,而且输出匹配行的后两行(After)
-B 2 #不仅输出匹配行,而且输出匹配行的前两行(Before)
-C 2 #不仅输出匹配行,而且输出匹配行的前后两行
示例:
ls --help | grep -A 2 "\-h" #查看ls -h参数的帮助信息(注意:转义符)
-n #输出匹配的行号
示例:
cat /etc/selinux/config | grep -n "^SELINUX"
-e #匹配正则表达式(更强大),和egrep命令是一样的
示例:
cat /etc/selinux/config | grep -e "^SELINUX"
cat /etc/selinux/config | egrep "^SELINUX"
sed
参考我的另一篇博客:
https://blog.csdn.net/NetRookieX/article/details/89419627
awk
推荐一个学习awk和其他Linux技术的博客:朱双印的博客
这是一种语言,拥有语言的特性。
擅长文本格式化。
逐行处理。这一点和grep、sed一样。
语句以分号;结束。
基本语法
awk [options] 'Pattern{Action}' file1 file2
举例
awk '{print}' 123.txt #输出各行
awk '{print $1,$3}' 123.txt #输出第1,3字段(不存在则不输出)
awk '{print $1,$3,"hello"}' 123.txt #输出自定义字符串
模式Pattern(条件)
关于Pattern
满足此条件才会执行Action
空模式
即没有模式
BEGIN/END模式
BEGIN #文本处理之前的动作
END #文本处理之后的动作
关系运算模式
!= #不等于
>= #大于等于
&& #短路与
正则模式
$0 ~ /^1/ #匹配正则(当使用{x,y}这种次数匹配的正则时,需加--posix选项或--re-interval选项)
!~ #不匹配此正则
行范围模式
'/正则1/,/正则2/{}' #匹配正则1到正则2的所有行(以第1次匹配为准)
变量
内置变量
$0 #代表当前行
$1 #第一个字段
NF #字段数
$NF #最后一个字段
$(NF-1) #倒数第2个字段
NR #当前处理的文本行的行号(多个文件看做整体)
FNR #当前处理的文本行的行号(多个文件分别看待)
ARGV #参数数组(分号内program不算参数,所以ARGV[0]为awk)
ARGC #参数个数
FILENAME #文件名
分割符
FS #输入分割符(field separator),默认为空白字符,即使有连续空白字符
OFS #输出分割符,默认为空格
RS #输入换行符
ORS #输出换行符
自定义变量
普通变量
方法1:-v varname=value
方法2:在program中直接定义
数组
默认从1开始!!!
未初始化的元素为空字符串""
下标可以为字符串
if(5 in arr) #判断是否存在下标为5的元素
delete arr["name"] #删除此元素
选项
-F: #指定:为输入分割符
-v FS=':' #指定:为输入分割符
动作
输出
print #输出换行符
printf #不输出换行符
awk '{printf "%s+%s\n" , $1,$2}' 123.txt #awk中printf替换符和参数数量必须一致,以逗号分隔
控制语句
if语句
awk '{ if(){} else if(){} else{} }' 123.txt
循环语句
与C中类似,for可以用for( i in arr)循环
可以用break,continue和exit
三元运算
条件?结果1:结果2
next语句
if(NR==2){next} #直接处理下一行
运算
关于运算
空字符串参与运算时看做0
运算符
++ #自增
内置函数
srand() #设置随机数种子
rand() #返回0到1的随机数
int(2.3) #强制转换
gsub
gsub("111","222",$1) #将第1个字段中111转换为222
gsub("^111","222",$1) #将第1个字段中开头的111转换为222
sub #与gsub比,sub只替换第1次匹配到的字符串
length("a") #返回1(字符串的长度)
index("hello","ll") #返回ll在hello中的位置(从1开始),返回0则不存在
split(str,arr,":") #以:分割,将字符串str存入数组arr中,下标从1开始
asort(arr1) #对数组进行从小到大排序,返回数组长度
asort(arr1,arr2) #对数组进行从小到大排序,返回数组长度,结果存入arr2中,原数组不改变
asorti(arr1,arr2) #与asort不同的是,asorti对arr1的下标排序后,将下标存入arr2中