sed 和awk常用命令集合备忘

本文详细介绍了sed与awk这两种强大的文本处理工具的基本用法及高级应用。包括sed的常用选项和命令,如删除、插入、替换等操作,以及awk的模式匹配、变量使用、条件判断等功能。通过实例演示如何利用它们高效地处理文件数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sed

 

选项:

 

-n :使用安静(silent)模式。在一般sed 的用法中,所有来自STDIN 的数据一般都会被列出到终端上。但如果加上-n 参数后,则只有经过sed

 

特殊处理的那一行(或者动作)才会被列出来。

-e :直接在命令列模式上进行 sed的动作编辑;

-f :直接将 sed的动作写在一个文件内, -f filename则可以运行 filename内的 sed动作;

-r sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)

-i :直接修改读取的文件内容,而不是输出到终端。

 

 

a :新增, a的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)

c :取代, c的后面可以接字串,这些字串可以取代 n1,n2之间的行!

d :删除,因为是删除啊,所以 d后面通常不接任何咚咚;

i :插入, i的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)

p :列印,亦即将某个选择的数据印出。通常 p会与参数 sed -n一起运行

s :取代,可以直接进行取代的工作哩!通常这个 s的动作可以搭配正规表示法!例如 1,20s/old/new/g就是啦!

 

 

nl /etc/passwd | sed '2,5d'/etc/passwd的内容列出并且列印行号,同时,请将第 2~5行删除

 

nl /etc/passwd | sed '2d' 只要删除第 2

 

nl /etc/passwd | sed '3,$d' 要删除第 3到最后一行

 

nl /etc/passwd | sed '2i drink tea' 那如果是要在第二行前

 

nl /etc/passwd | sed '2,5c No 2-5 number' 将第2-5行的内容取代成为『No 2-5 number』呢?

 

nl /etc/passwd | sed -n '5,7p'  仅列出 /etc/passwd文件内的第 5-7

 

如果是要增加两行以上,在第二行后面加入两行字,例如『Drink tea or .....』与『drink beer

 

 

sed -i '/^a.*/d' tmp.txt  -i 表示操作在源文件上生效.否则操作内存中数据,并不写入文件中.在分号内的/d表示删除匹配的行

sed -i 's/^a.*/haha/g' tmp.txt 分号内的s/表示替换/g表示全局替换.

 

$ sed 's/MA/Massachusetts/' list

——>找出MA并替换成Massachusetts,并列出内容(并不是在任何情况下都要将指令用单引号包围起来,但你应该养成这个习惯,如果不加单

 

引号,那么你就可能会得到一个错误提示  sed: -e expression #1, char 2: unterminated `s' command

 

2、关闭自动输出,只打印被修改行 ——>这里用了参数-n(关闭自动输出)p(打印被修改行)

$ sed -n -e 's/MA/Massachusetts/p' list

——>在命令行上编写多个语句时, 使用; 分隔或使用-e

如:sed 's/ MA/, Massachusetts/; s/ PA/, Pennsylvania/' list

sed -e 's/ MA/, Massachusetts/' -e 's/ PA/, Pennsylvania/' list

 

 

 

awk:

选项: -f 跟随脚本的文件名

-F 改变字段分隔符

-v 跟随 var= value

 

awk命令形式:

awk [-F|-f|-v] BEGIN{} //{command1; command2} END{}file

 [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量var=value

'  '          引用代码块

BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符

//           匹配代码块,可以是字符串或正则表达式

{}           命令代码块,包含一条或多条命令

         多条命令使用分号分隔

END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

 

内置变量:

 

$0           表示整个当前行

$1           每行第一个字段

NF          字段数量变量

NR          每行的记录号,多文件记录递增

FNR        NR类似,不过多文件记录不递增,每个文件都从1开始

\t            制表符

\n           换行符

FS          BEGIN时定义分隔符

RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)

~            匹配,与==相比不是精确比较

!~           不匹配,不精确比较

==         等于,必须全部相等,精确比较

!=           不等于,精确比较

&&      逻辑与

||             逻辑或

+            匹配时表示1个或1个以上

/[0-9][0-9]+/   两个或两个以上数字

/[0-9][0-9]*/    一个或一个以上数字

FILENAME 文件名

OFS      输出字段分隔符, 默认也是空格,可以改为制表符等

ORS        输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕

-F'[:#/]'   定义三个分隔符

 

 

print awk打印指定内容的主要命令

awk '{print}'  /etc/passwd   ==   awk '{print $0}'  /etc/passwd  

awk '{print " "}' /etc/passwd                                           //不输出passwd的内容,而是输出相同个数的空行,进一步解释

 

awk是一行一行处理文本

awk '{print "a"}'   /etc/passwd                                        //输出相同个数的a行,一行只有一个a字母

awk -F":" '{print $1}'  /etc/passwd

awk -F: '{print $1; print $2}'   /etc/passwd                   //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本

awk  -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd        //输出字段1,3,6,以制表符作为分隔符

 

 

$ awk '{ print $1 }' list       ——>列出第一列字段

$ awk '/MA/' list         ——>打印含有MA的行

$ awk '/MA/ { print $1 }'    ——>list打印含有MA的行的第一个字段

 

-f指定脚本文件

awk -f script.awk  file

BEGIN{

FS=":"

}

{print $1}               //效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定

 

awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test

I find 4 blank lines.

 ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}'                    //计算文件大小

total size is 17487

 

-F指定分隔符

$1 指指定分隔符后,第一个字段,$3第三个字段,\t是制表符

一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格

awk -F":" '{print $1}'  /etc/passwd

awk -F":" '{print $1 $3}'  /etc/passwd                       //$1$3相连输出,不分隔

awk -F":" '{print $1,$3}'  /etc/passwd                       //多了一个逗号,$1$3使用空格分隔

awk -F":" '{print $1 " " $3}'  /etc/passwd                  //$1$3之间手动添加空格分隔

awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd       //自定义输出  

awk -F: '{print NF}' /etc/passwd                                //显示每行有多少字段

awk -F: '{print $NF}' /etc/passwd                              //将每行第NF个字段的值打印出来

 awk -F: 'NF==4 {print }' /etc/passwd                       //显示只有4个字段的行

awk -F: 'NF>2{print $0}' /etc/passwd                       //显示每行字段数量大于2的行

awk '{print NR,$0}' /etc/passwd                                 //输出每行的行号

awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd      //依次打印行号,字段数,最后字段值,制表符,每行内容

awk -F: 'NR==5{print}'  /etc/passwd                         //显示第5

awk -F: 'NR==5 || NR==6{print}'  /etc/passwd       //显示第5行和第6

route -n|awk 'NR!=1{print}'                                       //不显示第一行

 

//匹配代码块

//纯字符匹配   !//纯字符不匹配   ~//字段值匹配    !~//字段值不匹配   ~/a1|a2/字段值匹配a1a2   

awk '/mysql/' /etc/passwd

awk '/mysql/{print }' /etc/passwd

awk '/mysql/{print $0}' /etc/passwd                   //三条指令结果一样

awk '!/mysql/{print $0}' /etc/passwd                  //输出不匹配mysql的行

awk '/mysql|mail/{print}' /etc/passwd

awk '!/mysql|mail/{print}' /etc/passwd

awk -F: '/mail/,/mysql/{print}' /etc/passwd         //区间匹配

awk '/[2][7][7]*/{print $0}' /etc/passwd               //匹配包含27为数字开头的行,如272772777...

awk -F: '$1~/mail/{print $1}' /etc/passwd           //$1匹配指定内容才显示

awk -F: '{if($1~/mail/) print $1}' /etc/passwd     //与上面相同

awk -F: '$1!~/mail/{print $1}' /etc/passwd          //不匹配

awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd        

 

IF语句

必须用在{}中,且比较内容用()扩起来

awk -F: '{if($1~/mail/) print $1}' /etc/passwd                                       //简写

awk -F: '{if($1~/mail/) {print $1}}'  /etc/passwd                                   //全写

awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd            //if...else...

 

 

条件表达式

==   !=   >   >=  

awk -F":" '$1=="mysql"{print $3}' /etc/passwd  

awk -F":" '{if($1=="mysql") print $3}' /etc/passwd          //与上面相同

awk -F":" '$1!="mysql"{print $3}' /etc/passwd                 //不等于

awk -F":" '$3>1000{print $3}' /etc/passwd                      //大于

awk -F":" '$3>=100{print $3}' /etc/passwd                     //大于等于

awk -F":" '$3<1{print $3}' /etc/passwd                            //小于

awk -F":" '$3<=1{print $3}' /etc/passwd                         //小于等于

 

逻辑运算符

&&||

awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd         //逻辑与,$1匹配mail,并且$3>8

awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd

awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd       //逻辑或

awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd

 

格式化输出

netstat -anp|awk '{printf "%-8s %-8s %-10s\n",$1,$2,$3}'

printf表示格式输出

%格式化输出分隔符

-8长度为8个字符

s表示字符串类型

打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8),

第三个字段输出字符串类型(长度为10)

netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s \n",$1,$2,$3}'

netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s \n",NR,$1,$2,$3}'

 

IF语句

awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd

small

small

small

large

small

small

awk -F: 'BEGIN{A=0;B=0} {if($3>100) {A++; print "large"} else {B++; print "small"}} END{print A,"\t",B}' /etc/passwd

                                                                                                                  //ID大于100,A

 

1,否则B1

awk -F: '{if($3<100) next; else print}' /etc/passwd                         //小于100跳过,否则显示

awk -F: 'BEGIN{i=1} {if(i<NF) print NR,NF,i++ }' /etc/passwd   

awk -F: 'BEGIN{i=1} {if(i<NF) {print NR,NF} i++ }' /etc/passwd

另一种形式

awk -F: '{print ($3>100 ? "yes":"no")}'  /etc/passwd

awk -F: '{print ($3>100 ? $3":\tyes":$3":\tno")}'  /etc/passwd

 

while语句

awk -F: 'BEGIN{i=1} {while(i<NF) print NF,$i,i++}' /etc/passwd

7 root 1

7 x 2

7 0 3

7 0 4

7 root 5

7 /root 6

 

数组

netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) print i,"\t",a[i]}'

netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s \n", i,"\t",a[i]}'

9523                               1     

9929                               1     

LISTEN                            6     

7903                               1     

3038/cupsd                   1     

7913                               1     

10837                             1     

9833                               1     

 

应用1

awk -F: '{print NF}' helloworld.sh                                                       //输出文件每行有多少字段

awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh                                 //输出前5个字段

awk -F: '{print $1,$2,$3,$4,$5}' OFS='\t' helloworld.sh                 //输出前5个字段并使用制表符分隔输出

awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh           //制表符分隔输出前5个字段,并打印行号

 

应用2

awk -F'[:#]' '{print NF}'  helloworld.sh                                                  //指定多个分隔符: #,输出每行多少字段

awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='\t' helloworld.sh   //制表符分隔输出多字段

 

应用3

awk -F'[:#/]' '{print NF}' helloworld.sh                                               //指定三个分隔符,并输出每行字段数

awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}' helloworld.sh     //制表符分隔输出多字段

 

应用4

计算/home目录下,普通文件的大小,使用KB作为单位

ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",sum/1024,"KB"}'

ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}'         //int是取整的意思

 

应用5

统计netstat -anp 状态为LISTENCONNECT的连接数量分别是多少

netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum[i]}'

 

应用6

统计/home目录下不同用户的普通文件的总数是多少?

ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum[i]}'   

mysql        199

root           374

统计/home目录下不同用户的普通文件的大小总size是多少?

ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i," ",sum[i]/1024/1024,"MB"}'

 

应用7

输出成绩表

awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno.   Name    No.    Math   English   Computer    Total\n";printf

 

"------------------------------------------------------------\n"}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-7s %-9s %-

 

10s %-7s \n",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{printf "------------------------------------------------------------\n";printf "%-

 

24s %-7s %-9s %-20s \n","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s \n","Avg:",math/NR,eng/NR,com/NR}' test0

 

[root@localhost home]# cat test0

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值