300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Linux Shell文本处理三剑客grep sed awk总结

Linux Shell文本处理三剑客grep sed awk总结

时间:2023-05-21 04:33:15

相关推荐

Linux Shell文本处理三剑客grep sed awk总结

目录

grep

sed工具

地址

基础命令:

高级编辑:

标签

awk

选项:

内置变量:

模式:

awk流程控制:

内置函数

I/O语句

自定义函数

grep

过滤来自一个文件或标准输入匹配模式内容。 除了 grep 外,还有 egrep、fgrep。egrep 是 grep 的扩展,相当于 grep -E。fgrep 相当于 grep - f,用的少。

用法:grep [OPTION]... PATTERN [FILE]...

常用选项:

-E:支持扩展正则表达式,默认支持基础正则表达式-e:指定多个模式匹配,相当于或-f:从文件每一行获取匹配模式-i:忽略大小写-w:模式匹配整个单词-x:模式匹配整行-v:打印不匹配的行-o:只打印匹配的内容-c:只打印每个文件匹配的行数-n:打印行号-A:打印匹配的后几行-B:打印匹配的前几行-C:打印匹配的前后几行

1)匹配多个模式

# echo "a bc de" |xargs -n1 |grep -e 'a' -e 'bc' a bc

2)去除空格 http.conf 文件空行或开头#号的行

grep -E -v "^$|^#" /etc/httpd/conf/httpd.conf

3)只显示匹配的字符串

# echo "this is a test" |grep -o 'is'isis

4)统计匹配多少行

# seq 1 20 |grep -c -E '[0-9]{2}'11

5) 匹配所有 IP

# ifconfig |grep -E -o "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"

6)打印匹配结果及前 3 行

# seq 1 10 |grep 5 -B 32345

sed工具

流编辑器,用于过滤和替换文本,以行为单位

工作原理:sed 命令将当前处理的行读入模式空间进行处理,处理完把结果输出,并清空模式空间(可以使用特殊命令不清除)。然后再将下一行读入模式空间进行处理输出,以此类推,直到最后一行。还有一个空间叫保持空间,又称暂存空间,可以暂时存放一些处理的数据,但不能直接输出,只能放到模式空间输出。 这两个空间其实就是在内存中初始化的一个内存区域,存放正在处理的数据和临时存放的数据。

用法:sed [选项] '地址 命令' file

常用选项

-n:使用安静模式,不打印模式空间,默认每次都会打印-e:多次编辑、执行脚本、表达式来处理,相当于分号-f:将sed的操作结果写在一个文件中-r:使用扩展正则表达式的语法,默认是基础正则表达式-i:直接修改文件的内容,比较危险

地址

1.单地址:

n:n为数字,表示处理单行$:表示最后一行/pattern/ :能够被此模式匹配到的每一行

2.地址范围:

省略地址:对全文进行操作n1,n2:从n1行到n2行first~step:从first行开始,每次增加step行;1~2奇数行,2~2偶数行first,+n:从first行开始,直到后面的n行/pattern/,+n:打印匹配行和它的后n行

基础命令:

a:目前的下一行新增,后面接新增的字符,也可以用\开头i:目前的上一行新增d:删除行p:打印c:替换整行s:替换字符,s///=:打印当前行号w /somefile:保存模式匹配的行至指定文件r /somefile:读取指定文件的文本至模式空间中

1.匹配打印(p)

打印奇数行: seq 10 |sed -n '1~2p'

不打印最后一行: tail /etc/services |sed -n '$!p'

使用变量:tail /etc/services |sed -n ''$a',3p';其中a是变量

sed 命令用单引号时,里面变量用单引号引起来,或者 sed 命令用双引号,因为双引号解释特殊符 号原有意义。

2.匹配删除(d)

去除空格 http.conf 文件空行或开头#号的行:

sed '/^#/d;/^$/d' /etc/httpd.conf

3.替换(s///)

[address]s/pattern/replacement/flags

flags用法如下:

tail /etc/services |sed 's/48049/&.0/' :表示把48049替换为48049.0

二次匹配替换:sed 's/blp5/test/;s/3g/4g/ ;也可以使用-e

高级编辑:

所有的 sed 命令都只是针对单行数据执行操作, 但是,有时我们需要对跨多行的数据执行特定操作。比如说,在文本中查找一串字符串"http://com",它很有可能出现在两行中,每行各包含其中一部分。

p:打印模式空间所有内容P:打印模式空间开端至\n内容,即打印第一个\n前面的内容Printn:读取匹配到的行的下一行覆盖至模式空间,预示着下一行提前进入,下一次就可以不读取下一行了,直接跳过N:将下一行追加至模式空间,多行处理,Nextd:删除模式空间,开始下一个循环D:如果模式空间包含换行符\n,删除第一个\n之前的内容。如果模式空间不包含\n,则会像发出d命令那样启动正常的新循环,Deleteh:把模式空间中的内容覆盖至保持空间H:把模式空间中的内容追加至保持空间中g:从保持空间取出数据覆盖模式空间G:从保持空间取出内容追加至模式空间x:把模式空间中的内容与保持空间中的内容进行互换!:取反,否定q:退出sed

1.读取下一行(n 和 N)

下一行加入到模式空间后,下一次不会读取它了

1)打印匹配的下一行:sed -n '/xx/{n;p};

因为n是覆盖,覆盖了匹配的xx,所以只输出下一行

2)打印偶数: seq 6 |sed -n 'n;p' ;

sed 先读取第一行 1,执行 n 命令,获取下一行 2,此时模式空间是 2,执行 p 命令,打印模式空 间。 现在模式空间是 2,sed 再读取 3,执行 n 命令,

3)打印奇数:seq 6 |sed 'n;d' ;

2.打印和删除模式空间第一行(P 和 D)

1)打印奇数:seq 6 |sed -n 'N;P'

读取第一行 1,执行 N 命令读取下一行并追加到模式空间,此时模式空间是 1\n2,执行 D 命令删除 模式空间第一行 1,剩余 2。

3.保持空间操作(h 与 H、g 与 G 和 x)

1)将匹配的内容覆盖到另一个匹配: seq 6 |sed -e '/3/{h;d}' -e '/5/g'

h 命令把匹配的 3 复制到保持空间,d 命令删除模式空间的 3。后面命令再对模式空间匹配 5,并用 g 命令把保持空间 3 覆盖模式空间 5。

标签

: lable name 定义标签b lable 跳转到指定标签,如果没有标签则到脚本末尾t lable 跳转到指定标签,前提是 s///命令执行成

# seq 6 |sed ':a;N;s/\n/,/;b a'1,2,3,4,5,6

看看这里的标签使用,:a 是定义的标签名,b a 是跳转到 a 位置。 sed 读取第一行 1,N 命令读取下一行 2,此时模式空间是 1\n2$,执行替换,此时模式空间是 1,2$,执行 b 命令再跳转到标签 a 位置继续执行 N 命令,读取下一行 3 追加到模式空间,此时模式 空间是 1,2\n3$,再替换,以此类推,不断追加替换,直到最后一行 N 读不到下一行内容退出。

awk

基本的命令语法:awk option '模式1 {操作1} 模式2 {操作2} …… ' file

awk倾向于一行当中分成数个字段来处理。默认的分割字符为空格和制表符tab。

选项:

-f:从文件读取awk程序源文件,文件内容应该是 模式+操作那部分-F:指定字段分隔符--posix :兼容 POSIX 正则表达式-v var=value :定义变量并赋值,可以修改内置变量

内置变量:

1.自定义变量

[root@com ~]# cat hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1localhost localhost.localdomain localhost6 localhost6.localdomain6[root@com ~]# awk -v x="xx" -v y="${SHELL}" '{print x,y}' hostsxx /bin/bashxx /bin/bash

如果要直接使用环境变量,需要'{print " ' $SHELL' " }' ,双引号加单引号包起来,或直接使用一个单引号

awk中变量不需定义就可以直接使用,作为字符处理时未定义的变量默认值为空,作为数字处理时未定义的变量默认值为0

2.自定义分隔符

head -n 3 /etc/passwd | awk -F ":" '{print $1,$2}'head -n 3 /etc/passwd | awk 'BEGIN{FS=":"}{print $1,$2}'

使用-F或BEGIN{FS=}

也可以使用多个分隔符:-F "[: ]" ,[ ]元字符的意思是符号其中任意一个字符

3.内置变量RS、OFS、ORS

RS:指定每条记录间的分隔符

awk -v RS="." '{print $1}' /tmp/hosts #指定.作为行分隔符,当遇到.才把前面的数据视为一行,视为一条记录

OFS:指定输出的列之间的分隔符

[root@com ~]# awk -v OFS="\t-" '{print $1,$2}' hosts #设置为TAB-127.0.0.1 -localhost::1 -localhost

ORS:指定输出的记录之间的分割符

[root@com ~]# awk -v ORS="\t" '{print $1,$2}' hosts #指定每条记录不换行,用tab分隔127.0.0.1 localhost ::1 localhost [root@com ~]#

模式:

除了正则相关的,还支持非常多的运算:==、!=、>、<、?:、*= ……

#打印每行中有tcp的行:awk '/tcp/{print $0}'#打印每条记录第2列有tcp的行:awk '$2~/tcp/{print $0}'#打印第一列等于blp5或isnetserv的行awk '$1=="blp5"||$1=="isnetserv"{print $0}'#打印第10行的数据awk 'NR==10{print $0}'#统计有多少个客户端登录rootwho | awk '$1=="root"{x++} END{print x}' #打印1~200之间能被6整除且包含数字6的整数数字seq 200 | awk '$1%6==0 && $1~/6/'

awk流程控制:

1)if语句:

if(判断条件){动作指令1;} [ else {动作指令2;} ]

#输出uid大于等于1000的行cat /etc/passwd | awk 'BEGIN{FS=":"}{if($3>=1000)print $0}'#带elseseq 5 |awk '{if($0==3)print $0;else print "no"}'

2)while语句:

#打印每个字段awk 'BEGIN{FS=":"}{i=1;while(i<=NF){print $i;i++;}}'

3)for 语句 C 语言风格

awk '{for(i=1;i<=NF;i++)print $i}' file

4)for 语句遍历数组

[root@com ~]# awk 'BEGIN{a[0]=1;a[2]=2;a["n"]=3;for(i in a){printf i"---"a[i]"\n"}}'n---30---12---2

5)中断

与shell类似,awk提供了continue、break、exit循环中断语句

awk 'BEGIN{for(i=1;i<=5;i++){if(i==3){break};print i}}'

内置函数

1)int取整

# echo -e "123.11\n123abc\nabc123" | awk -v ORS=" " '{print int($0)}END{print "\n"}'123 123 0

2)rand()和 srand()

#awk '{srand();print rand() }'0.447679#awk 'BEGIN{srand();print int(rand()*10)}'4

3)asort()

#awk 'BEGIN{a[0]=2;a[1]=13;a[3]=8;a["nihao"]=1;s=asort(a,b)}END{for(i=1;i<s;i++){print b[i]}} '128#awk 'BEGIN{a[0]=2;a[1]=13;a[3]=8;a["nihao"]=1; s=asort(a,b)}END{for(i in b){print b[i]}} '13128

4)sub()和 gsub()

替换正则匹配的字符串:# tail /etc/services |awk '/blp5/{sub(/tcp/,"icmp");print $0}'blp5 48129/icmp # Bloomberg locatorblp5 48129/udp # Bloomberg locator# tail /etc/services |awk '/blp5/{gsub(/c/,"9");print $0}'blp5 48129/t9p # Bloomberg lo9atorblp5 48129/udp # Bloomberg lo9ator

4)index

# echo "abc" |awk '{print index($0,"bc")}'2

5)match

# echo "123abc#456cde 789aaa#234bbb 999aaa#aaabbb" |xargs -n1 |awk '{print match($0,234)}' 080

6)split

# echo "abc:def:ghi" | awk '{split($0,a,":");for(i=1;i<=length(a);i++)print a[i]}'abcdefghi

7)substr

# echo "abcdefg" | awk '{print substr($0,3)}'cdefg

8)时间处理

# echo 1 | awk 'BEGIN{print systime()}'1652773555# echo 1 | awk 'BEGIN{print systime()}' | awk '{print strftime("%Y-%m-%d %H:%M:%S",$0)}'-05-17 15:05:36

I/O语句

1)getline :

能让awk立刻读取下一行数据(读取下一条记录并复制给$0,并重新设置NF、NR和FNR);getline var不会复制给$0

# seq 5 | awk '/3/{print;getline;print $0;}'34# seq 5 | awk '{getline a;print a;}' 244

2)next:

停止处理当前的输入记录,立刻读取下一条记录并返回awk程序的第一个模式匹配重新处理数据。有点类似于循环语句中的continue,不会执行当次循环的后续语句

3)system:

# awk 'BEGIN{if(system("grep root /etc/passwd &>/dev/null")==0)print "yes";else print "no"}'yes

4)printf格式:

自定义函数

格式:function name(parameter list) { statements }

# awk 'function myfunc(a,b){return a+b}BEGIN{print myfunc(1,2)}'3

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。