shell awk命令笔记

本文介绍正则表达式的常用元素及awk的基础用法,包括模式匹配、字符串过滤及文件拆分等实用技巧。

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

#正则表达式的一些最基本的东西:
^ 表示一行的开头。如:/^#/ 以#开头的匹配。
$ 表示一行的结尾。如:/}$/ 以}结尾的匹配。
\< 表示词首。 如:\<abc 表示以 abc 为首的詞。
\> 表示词尾。 如:abc\> 表示以 abc 結尾的詞。
. 表示任何单个字符。
* 表示某个字符出现了0次或多次。
[ ] 字符集合。 如:[abc] 表示匹配a或b或c,
还有 [a-zA-Z] 表示匹配所有的26个字符。
如果其中有^表示反,如 [^a] 表示非a的字符

awk 把文件逐行的读入,以空格(可以指定)为默认分隔符将每行切片,切开的部分再进行各种分析处理。awk 是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

awk '{/pattern/ + action}' {filenames}
#       匹配     动作


#示例 
awk  '{print $1}' file #文件第一列,默认分隔符是"空白键" 或 "[tab]键"
awk  -F ':' '{print $1}' file  #-F 指定域分隔符为':'
awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7} END {print "blue,/bin/nosh"}'
#先执行BEGING,然后读取文件,直到所有的记录都读完,最后执行END操作。

#如果你要指定多个分隔符,你可以这样来:
awk -F '[;:]'

awk -F: '/root/' file  #包含root的行
awk -F: '/root/{print $7}' /etc/passwd #显示匹配上的第7$0 当前记录(这个变量中存放着整个行的内容)
$1~$n  当前记录的第n个字段,字段间由FS分隔
FS  输入字段分隔符 默认是空格或Tab
RS  输入的记录分隔符, 默认为换行符
NF  当前记录中的字段个数,就是有多少列
NR  已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
OFS 输出字段分隔符, 默认也是空格
ORS 输出的记录分隔符,默认为换行符
FILENAME    当前输入文件的名字

#awk 内置变量
ARGC               命令行参数个数
ARGV               命令行参数排列
ENVIRON            支持队列中系统环境变量的使用
FILENAME           awk浏览的文件名
FNR                浏览文件的记录数
FS                 设置输入域分隔符,等价 -F选项
NF                 浏览记录的域的个数
NR                 已读的记录数
OFS                输出域分隔符
ORS                输出记录分隔符
RS                 控制记录分隔符
$0变量是指整条记录
$1表示当前行的第一个域
$2表示当前行的第二个域


print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。

printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。
$ awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}' netstat.txt
Proto    Recv-Q   Send-Q   Local-Address      Foreign-Address        State
tcp      0        0        0.0.0.0:3306       0.0.0.0:*              LISTEN
tcp      0        0        0.0.0.0:80         0.0.0.0:*              LISTEN
tcp      0        0        127.0.0.1:9000     0.0.0.0:*              LISTEN

#awk编程

##过滤记录####
#我们再来看看如何过滤记录
#(下面过滤条件为:第三列的值为0 && 第6列的值为LISTEN)
awk '$3==0 && $6=="LISTEN" ' netstat.txt

#第一行作为表头,我们可以引入内建变量NR:
awk '$3==0 && $6=="LISTEN" || NR==1 ' netstat.txt

#格式化输出
awk '$3==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt


#以\t作为分隔符输出的例子(下面使用了/etc/passwd文件,这个文件是以:分隔的):
awk  -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd


### 字符串匹配
awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
1       Local-Address   Foreign-Address State
6       coolshell.cn:80 61.140.101.185:37538    FIN_WAIT2
9       coolshell.cn:80 116.234.127.77:11502    FIN_WAIT2
#匹配FIN状态。
#其实 ~ 表示模式开始。/ /中是模式。这就是一个正则表达式的匹配。
awk '$6 ~ /FIN|TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
#匹配FIN 或者 TIME

awk '/LISTEN/' netstat.txt
#其实awk可以像grep一样的去匹配第一行

#模式取反的例子:
awk '$6 !~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt



## 折分文件
#awk拆分文件很简单,使用重定向就好了。下面这个例子,
#是按第6例分隔文件,相当的简单(其中的NR!=1表示不处理表头)。
awk 'NR!=1{print > $6}' netstat.txt
#文件夹下会生成以第六列的变量为名字的文件

#再复杂一点:(注意其中的if-else-if语句,可见awk其实是个脚本解释器)
awk 'NR!=1{if($6 ~ /TIME|ESTABLISHED/) print > "1.txt";
else if($6 ~ /LISTEN/) print > "2.txt";
else print > "3.txt" }' netstat.txt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值