简述
awk、grep、sed是linux操作文本的三大利器,合称文本三剑客,三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂。grep更适合单纯的查找或匹配文本,sed更适合编辑匹配到的文本,awk更适合格式化文本,对文本进行较复杂格式处理。
grep
grep (Global Regular Expression Print)用于搜索/过滤特定字符,可以使用正则表达式通过返回一个状态值来说明,如果模板搜索成功,返回0,不成功,返回1,文件不存在,返回2;可以利用返回值进行自动化的文本处理工作。
egrep = grep -E:扩展的正则表达式 (除了< , > , \b 使用其他正则都可以去掉\)
#输出file中含有hello字符串的行的数量
grep -c "hello" file
#输出file中含有hello的数量
grep -o "hello" file | wc -l
#递归查找指定文件或目录中含有hello的行,并输出;
grep -r "hello" /etc
#查找含有hello或者world的行;
grep -e "hello" -e "world" file
#搜索src目录中.c和.cpp文件中含有main的行;
grep -r "main" ./src --include *.{c,cpp}
#搜索src目录中含有main的行,但不搜索abc文件;
grep -r "main" ./src --exclude "abc"
#搜索src目录中含有main的行,但不搜索.git文件夹;
grep -r "main" ./src --exclude-dir ".git"
#删除含有hello字符串的文件
grep -r "hello" ./src -lZ | xargs -0 rm -f
#将file中含有root的行取出
grep root file
or
cat file | grep root
#将没有root的行取出
grep -v root /home/file
#将没有出现root和nologin的行取出
grep -v root /etc/passwd | grep -v nologin
#在当前目录查找带有’hello‘行的文件
grep 'hello' *
#在当前目录及子目录下搜索’hello‘行的文件,但不显示匹配的行,显示匹配的文件;
grep -i -r 'hello' *
#过滤注释行和空行
grep -Ev "^$|[#;]" file1
#在文件'file1'里查找"str"
grep str /home/file1
#在'home'目录和子目录的文件中查找"str"
grep str -r /home/*
awk
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
取行和列
#获取文本第1,3列的值,NF表示字段数,在执行过程中对应于当前的字段数,$为行尾定位符
awk '{print $1,$3}' log.txt
#取最后一列
awk ‘{print $NF}'
#取指定行,NR表示从awk开始执行后,按照记录分隔符读取的数据次数,默认的记录分隔符为换行符,因此默认的就是读取的数据行数
ps -aux|awk 'NR==3'
#输出匹配的列
docker images|awk '/d2/ {print $3}'
#取m行到n行中的k字段
awk 'NR==m,NR==n {print $k}' filename
# 取n行k列
awk 'NR==m {print $k}' filename
#获取内存可用量并且判断是否小于1024
FreeMem=`free -m | grep Mem | awk '{print $4}'[ $FreeMem -lt 1024 ] && echo "Insufficient Memory"
#匹配行首和行尾
awk '/^xxx.*?yyy/'
#统计行数
awk 'BEGIN { i=0 } { i++ } END { print i}' filename
or
awk 'END { print NR }' filename
#print能够接受参数;
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3 ; }' //该命令输出如下 v1 v2 v3
#awk 默认的分割符为空格和制表符,使用 -F 参数来指定分隔符
awk -F ':' '{print $1}' /etc/passwd
#计算剩余内存百分比
free -m | awk 'NR==2' | awk '{a=$2; b=$4; print b / a * 100}'
#它会在开始读取一个文件之前,运行一次 BEGIN关键字后面的脚本代码段,BEGIN后面的脚本代码段只会执行一次
awk 'BEGIN {print "Start read file"} {print $0}' /etc/passwd
#在 awk 读取并且处理完文件的所有内容行之后,才会执行 END 后面的脚本代码段
awk 'END {print "End file"}' /etc/passwd
awk 'BEGIN {print "Start read file"} {print $0} END {print "End file"}' /etc/passwd
sed
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(patternspace ),接着用sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’ 的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出或-i。
功能:主要用来自动编辑一个或多个文件, 简化对文件的反复操作
插入和修改
#插入指定行的下一行
sed -i '101 a\ 1111'
#将test替换为mytest,sed 命令一般是写在单引号内,引号内开头的 s 表示替换(substitute)
sed 's/test/mytest/' file
#在默认情况下,sed 只会替换每行中匹配到的第一个字符串,如果希望替换每一行中所有匹配到的字符串,需加在命令末尾上选项 g
sed 's/Jack/Mark/g' fin.txt
# 2~3 行中的 hello 替换成 hey
sed '2,3s/hello/hey/g' fin.txt
#在指定某一行的前面或者后面添加一行
sed -i '1i\welcome' fin.txt
#这里的 1 表示第一行, i 表示在这一行前面添加一行,如果要在第一行后面添加一行,则用字母 a :
sed -i '1a\welcome' fin.txt
#字母 a 是 append ,在后面添加一行
#字母 i 是 insert, 在前面添加一行
#在匹配行的前面或者后面添加一行
sed -i '/Pony/a\welcome' fin.txt
#在后面添加一行用字母 a,在前面添加一行用字母 i
sed -i '/Pony/i\welcome' fin.txt
#找出包含字符 Pony 的那些行,将这些行中的 hello 替换成 hey
sed '/Pony/s/hello/hey/g' fin.txt
#在1111之 前 添加AAA,sed -i 's/指定的字符/要插入的字符&/' 文件
sed -i 's/1111/AAA&/' /tmp/input.txt
#在1111之 后 添加BBB,sed -i 's/指定的字符/&要插入的字符/' 文件
sed -i 's/1111/&BBB/' /tmp/input.txt
#删除 2~3 行,命令中的 d 表示删除(delete)
sed '2,3d' fin.txt
#删除包含字符串 Pony 的行
sed '/Pony/d' fin.txt
#删除不包含字符 Pony 的行,这里的感叹号!表示反选,斜杠表示转义
sed '/Pony/\!d' fin.txt
#删除空白行, 这里的 ^ 匹配一行的开头, $ 匹配一行的结尾,所以 /^$/ 就表示一行的开头和结尾之间没有任何内容,也就是空白行;
sed '/^$/d' fin.txt
#注意有时候有些空白行是包含空格的,这种情况就需要写成:
sed '/^\s*$/d' fin.txt
#其中 \s 表示空格, 星号 * 表示前面的字符重复 0 次或多次,所以这种写法可以匹配那些包含任意个空格的空白行
#删除字符“,”
echo "hello,123,word" | sed 's/,//g'