48小时系统班试听入口

Linux命令之文本三剑客

发布作者:新盟教育 发布日期:2021-12-03 浏览人数:20000人

速来学习!


Grep/Awk/Sed文本三剑客

 

Sed

 

依照脚本指令来处理、编辑文本文件;用来自动编辑一个或者多个文件、简化对文件的反复操作、编写转换程序。

 

注意sed的操作并不会改变源文件!

 

sed [-hnV] [-e<script>] [-f<script文件>] [文本文件]

### 参数说明:

# -h或--help 显示帮助

# -n或--quiet或--silent 仅显示处理的结果

# -V或--version 显示版本信息

# -e<script>或--expression=<script> 以指定脚本指令处理文本文件

# -f<script文件>或--file=<script文件> 以选项中指定的脚本文件来处理文本文件

### 动作说明:

#a: append(新增) a前为行数,a后为新增内容,新增内容为当前行的下一行

#c: 取代 c前为n1,n2行数 ,c后为取代内容,用于取代n1-n2行的内容

#d: 删除,d后无内容

#i: insert(插入) i前为行数,i后为插入内容,插入内容在当前行的前一行

#p: 打印;通常与 -n 一起运行

#s: 取代;可以搭配正则使用;格式:‘s/old/new/g’(!!!!!)

 

实例1:给文件添加行:在第四行后面添加行。

 

sed -e 4a\wohaoshuai sed_test.txt

 

实例2:删除文件指定行。

 

sed -e 4,5d 

sed_test.txtsed -e '6.$d' sed_test.txt

 

实例3:插入指定行。

 

sed -e 2i\ilikecocokele

sed_test.txtsed -e '2i ilikecocokele' sed_test.txt

 

实例4:替换指定行。

 

sed -e 2,5c\nnumber

sed_test.txtsed -e '2,5c number' sed_test.txt

 

实例5:打印出指定行。

 

sed -n 2,5p sed_test.txt #仅显示处理的结果 -n 与p 经常搭配使用

 

实例6:数据搜寻并显示。

 

sed -n '/ccccc/p' sed_test.txt  # 格式:/搜索内容/

nl sed_test.txt | sed -n '/CCC/p' # nl相当于能够显示行号的cat

 

实例7:数据搜寻并删除。

· 

sed -n '/CCCCC/d' sed_test.txt

nl sed_test.txt | sed '/CCCC/d'

 

实例8:数据搜寻并替换。

 

#格式:sed 's/要被替代的字符串/新的字符串/g';多结合正则表达式一起用;

# 将ip(inet addr:及之前)前面的内容删除

nl sed_test.txt | grep 'inet addr' | sed 's/^.*addr://g' 

#grep是先匹配到相关行# 将ip(Mask:及之后)之后的内容删除

nl sed_test.txt | grep 'inet addr' | sed 's/Bcast:.*$//g'

 

实例9:数据搜寻并执行命令;命令包括在花括号里面,每个命令之间用分号分隔。

 

nl sed_test.txt | sed -n '/EEEE/{s/EEEEE/eeee/;p;q}'  #p:打印;q:只匹配第一个;

 

Grep

 

用于查找文件中符合条件的字符串:将文件中符合范本样式的那一列显示出来。

 

若不指定文件或者给与的文件名为-,则grep指令会从标准输入设备读取数据。

 

grep [-ciovw][-A<显示数量>][-B<显示数量>][-C<显示数量>][-d<进行动作>][-e<范式样本样本>][-f<范式文件>][范式样本][文本或目录]

# -A<显示数量>:除匹配行,并显示该行之后的内容

# -B<显示数量>: 除匹配行,并显示该行之前的内容

# -C<显示数量>:除匹配行,并显示该行前后的内容

# -d<进行动作>:查找对象是目录必须使用

# -e<范式样本样本>:指定字符串为查找的样式

# -f<范式文件>:相当于多个匹配样式的集合


# -c: 计算符合样式的数量

# -i: 忽略字符大小写差异

# -o: 只显示匹配样式部分

# -v: 显示不包含匹配项的所有行

# -w:只显示完全匹配(全字匹配)的行

 

案例1:当前目录下查找后缀为file的文件中包含test字符串的文件。

 

grep test *file

 

案例2:递归查找目录下包含test的行。

 

grep -r test ~

 

案例3:反向查找当前目录下所有包含test文件中的包含test的行。

 

grep -v test *test*

 

Awk

 

处理文本的语言,强大的文本分析工具。

 

awk [选项参数] 'script' var=value file(s)

awk [选项参数] -f scriptfile var=value file(s)

#### 选项参数

-F fs # 指定输入文件拆分隔符,fs是一个字符串或是一个正则表达式

-v var # 赋值一个用户定义变量

-f scriptfile # 从脚本中读取awk命令

 

生成测试内容的awk_test.txt文件。

 

cat <<EOF >awk_test.txt

2 this is a test

3 Are you like awk

This's a test

10 There are orange,apple,mongo

EOF

 

用法一:awk ‘{[pattern] action}’ {filenames} 行匹配语句awk ''只能使用单引号。

 

# 每行按空格/tab分隔,输出第1、4项

$ awk '{print $1,$4}' awk_test.txt

2 a

3 like

This's

10 orange,apple,mongo

# 每行按空格/tab分隔,输出第1、4项,并格式化

$ awk '{printf "%-8s %-10s\n", $1,$4}' awk_test.txt

2        a

3        like

This's

10       orange,apple,mongo

 

用法二:awk -F # -F相当于内置变量FS,指定分隔符。

 

#每行按,分隔,输出第1、4项

$ awk -F, '{print $1,$2}' awk_test.txt

2 this is a test

3 Are you like awk

This's a test

10 There are orange apple

#使用多个分割符:空格 ,

$ awk -F '[ ,]' '{print $1,$2,$5}' awk_test.txt

2 this test

3 Are awk

This's a

10 There apple

 

用法三:awk -v # 设置变量。

 

$ awk -va=1 '{print $1,$1+a}' awk_test.txt

2 3

3 4

This's 1

10 11

$ awk -va=1 -vb=s '{print $1,$1+a,$1b}' awk_test.txt

2 3 2s

3 4 3s

This's 1 This'ss

10 11 10s

 

用法四: awk -f {awk脚本} {文件名}。

 

awk -f cal.awk awk_test.txt

 

运算符

 

运算符  描述

= += -= *= /= %= ^= **=  赋值

?:  C条件表达式

|| &&  逻辑或 与

~ !~  匹配 或 不匹配正则表达式

< <= > >= != ==  关系运算符

空格  连接

+ -  加,减

* / %  乘 除 求余

+ - !一元加,减,逻辑非

^ ***  求幂

++ –  增加 或 减少,作为前缀或后缀

$  字段引用

in  数组成员

 

内建变量

 

变量  描述

$n  当前记录的第n个字段,字段间由FS分隔

$0  完整的输入记录

ARGC  命令行参数的数目

ARGIND  命令行中当前文件的位置(从0开始算)

ARGV  包含命令行参数的数组

CONVFMT  数字转换格式(默认值为%.6g)

ENVIRON环境变量关联数组

ERRNO  最后一个系统错误的描述

FIELDWIDTHS  字段宽度列表(用空格键分隔)

FILENAME  当前文件名

FNR  各文件分别计数的行号

FS  字段分隔符(默认任何空格)

IGNORECASE  如果为真,则进行忽略大小写的匹配当前文件名

NF  一条记录的字段的数目

NR  已经读出的记录数,就是行号,从1开始字段分隔符(默认是任何空格)

OFMT  数字的输出格式(默认值是%.6g)

OFS  输出记录分隔符(输出换行符),输出时用指定的符号代替换行符

ORS  输出记录分隔符(默认值是一个换行符)

RLENGTH  match函数所匹配的字符串的长度

RS  记录分隔符(默认是一个换行符)

RSTART  match函数所匹配的字符串的第一个位置

SUBSEP  数组下标分隔符(默认值是/034

 

awk脚本,注意两个关键词 BEGIN 和 END:

 

BEGIN{ 这里面放的是执行前的语句 }。


END {这里面放的是处理完所有的行后要执行的语句 }。

 

{这里面放的是处理每一行时要执行的语句}。

 

# 过滤第一列大于2的行

$ awk '$1>2' awk_test.txt

Are you like awk

This's a test

10 There are orange,apple,mongo

# 过滤第一列等于2的行

$ awk '$1==2 {print $1,$3}' awk_test.txt

2 is

# 过滤第一列大于2并且第二列等于’Are‘的行

$ awk '$1>2 && $2=="Are" {print $1,$3}' awk_test.txt

3 you

$ awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt

FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS

log.txt    2    1         5    1

log.txt    2    2         5    2

log.txt    2    3         3    3

log.txt    2    4         4    4

$ awk -F\' 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt

FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS

---------------------------------------------

log.txt    2    1    '    1    1

log.txt    2    2    '    1    2

log.txt    2    3    '    2    3

log.txt    2    4    '    1    4

# 输出顺序号 NR, 匹配文本行号

$ awk '{print NR,FNR,$1,$2,$3}' log.txt

1 1 2 this is

2 2 3 Are you

3 3 This's a test

4 4 10 There are

# 指定输出分割符

$  awk '{print $1,$2,$5}' OFS=" $ "  log.txt

$ this $ test

$ Are $ awk

This's $ a $

10 $ There $

#### 使用正则:~表示模式开始,//中是模式

# 输出第二列包含 "th",并打印第二列与第四列;

$ awk '$2 ~ /th/ {print $2,$4}' log.txt

this a

# 输出包含 "re" 的行

$ awk '/re/ ' log.txt

3 Are you like awk

10 There are orange,apple,mongo

#### 忽略大小写

$ awk 'BEGIN{IGNORECASE=1} /this/' log.txt

2 this is a test

This's a test

#### 反向匹配

$ awk '$2 !~ /th/ {print $2,$4}' log.txt

Are like

aThere orange,apple,mongo

$ awk '!/th/ {print $2,$4}' log.txt

Are like

A

There orange,apple,mongo

#### awk脚本

$ cat score.txt

Marry   2143 78 84 77

Jack    2321 66 78 45

Tom     2122 48 77 71

Mike    2537 87 97 95

Bob     2415 40 57 62

$ cat cal.awk

#!/bin/awk -f

#运行前

BEGIN {    

math = 0    

english = 0    

computer = 0     

printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"    

printf "---------------------------------------------\n"

}

#运行中

{

math+=$3    

english+=$4    

computer+=$5    

printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5

}

#运行后

END {

printf "---------------------------------------------\n"    

printf "  TOTAL:%10d %8d %8d \n", math, english, computer    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR}

$ awk -f cal.awk score.txt

NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL

Marry  2143     78       84       77      239

Jack   2321     66       78       45      189

Tom    2122     48       77       71      196

Mike   2537     87       97       95      279

Bob    2415     40       57       62      159

  TOTAL:       319      393      350

AVERAGE:     63.80    78.60    70.00

# 计算文件大小

$ ls -l *.txt | awk '{sum+=$5} END {print sum}'

666581

# 从文件中找出长度大于80的行

awk 'length>80' log.txt

# 打印九九乘法表

seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

 

简单总结

 

grep: 单纯查找或匹配文本。

 

sed: 编辑匹配到的文本。

 

awk: 格式化文本,文本复杂格式处理。



如果有朋友需要自学,或者没有很好的学习途径,那么可以看一下这个视频:


http://www.thinkmo.cn/Home/Course/nradio/course_id/50 .html


这是一个零基础入门的教程,对于刚开始接触Linux运维的同学还是很友好的,希望对你有帮助。