04--Linux awk用法

一、awk命令简介

awk是一个强大的文本分析工具。awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

二、awk命令格式及选项

语法形式

awk [options] 'script' var=value file(s)

awk [options] -f scriptfile var=value file(s)

常用命令选项

-F fs fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:

-v var=value 赋值一个用户定义变量,将外部变量传递给awk

-f scripfile 从脚本文件中读取awk命令

-m[fr] val 对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用

三、awk的原理

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

第一步:执行BEGIN{ commands }语句块中的语句;
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{ commands }语句块。

四、awk 基本用法

awk的调用有三种方式

1.命令行方式

awk [-F field-separator] 'commands' input-file(s)

其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

2.shell脚本方式

awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file

一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成,这三个部分是可选的。

任意一个部分都可以不出现在脚本中,脚本通常是被单引号或双引号中,例如:

awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename

awk "BEGIN{ i=0 } { i++ } END{ print i }" filename

3.将所有的awk命令插入一个单独文件,然后调用

awk -f awk-script-file input-file(s)

其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的命令行方式是一样的。

我们通过几个简单的示例来进一步了解awk的用法

[root@localhost ~]# awk '{print $0}' /etc/passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
.........................................................................
[root@localhost ~]# echo 123|awk '{print "hello,awk"}'
hello,awk

[root@localhost ~]# awk '{print "hi"}' /etc/passwd
hi
hi
hi
hi
hi
hi
hi
hi
hi
.........................................................................

我们指定/etc/passwd作为输出文件,执行awk时,它就会依次对/etc/passwd中的每一行执行print命令。

Linux awk用法

 

awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键",所以$1表示登录用户,$3表示登录用户ip,以此类推。如

打印/etc/passwd下所有的用户名
[root@localhost ~]# awk -F: '{print $1}' /etc/passwd
root
bin
daemon
adm
........................................................................
打印/etc/passwd下所有的用户名及UID
[root@localhost ~]# awk -F: '{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
........................................................................
以username: XXX  uid: XXX格式输出

[root@localhost ~]# awk -F: '{print "username: " $1 "\t\tuid: "$3}' /etc/passwd
username: root      uid: 0
username: bin       uid: 1
username: daemon        uid: 2
........................................................................

五、awk内置变量

变量描述
\$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)

示例

[root@localhost ~]# echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7" | awk '{print "Line No:"NR", No of fields:"NF, "$0="$0, "$1="$1, "$2="$2, "$3="$3}'
Line No:1, No of fields:3 $0=line1 f2 f3 $1=line1 $2=f2 $3=f3
Line No:2, No of fields:3 $0=line2 f4 f5 $1=line2 $2=f4 $3=f5
Line No:3, No of fields:3 $0=line3 f6 f7 $1=line3 $2=f6 $3=f7

使用print $NF可以打印出一行中的最后一个字段,使用$(NF-1)则是打印倒数第二个字段,其他以此类推:

[root@localhost ~]# echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print $NF}'
f3
f5
[root@localhost ~]# echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print $(NF-1)}'
f2
f4

统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

[root@localhost ~]# awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:bin:x:1:1:bin:/bin:/sbin/nologin
filename:/etc/passwd,linenumber:3,columns:7,linecontent:daemon:x:2:2:daemon:/sbin:/sbin/nologin

统计/etc/passwd文件中的命令行参数ARGC,文件行号FNR,字段分隔符FS,一条记录的字段数目NF,已经读出的记录数(默认是行号)NR

[root@localhost ~]# awk -F: 'BEGIN{printf "%4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR}'  /etc/passwd
FILENAME ARGC  FNR   FS   NF   NR
---------------------------------------------
/etc/passwd    2    1    :    7    1
/etc/passwd    2    2    :    7    2
/etc/passwd    2    3    :    7    3

六、awk高级用法

1.awk赋值运算

赋值语句运算符:= += -= *= /= %= ^= **=

例如:a+=5;等价于a=a+5

[root@localhost ~]# awk 'BEGIN{a=5;a+=5;print a}'
10

2.awk正则运算

输出包含有root的行,并打印用户名和UID及原行内容

[root@localhost ~]# awk -F: '/root/ {print $1,$3,$0}' /etc/passwd
root 0 root:x:0:0:root:/root:/bin/bash
operator 11 operator:x:11:0:operator:/root:/sbin/nologin

我们发现找到了两行,如果我们想找root开头的行就要这样写:awk -F: '/^root/' /etc/passwd

3.awk三目运算

[root@localhost ~]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}'
ok
[root@localhost ~]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}'
err

三目运算其实就是一个判断运算,如果为真则输出?后的内容,如果为假则输出:后的内容

4.awk的循环运用

if语句运用

[root@localhost ~]# awk 'BEGIN{ test=100;if(test>90){ print "vear good";} else{print "no pass";}}'

vear good

每条命令后用结尾

while循环运用

计算从1累加到100的值

[root@localhost ~]# awk 'BEGIN{test=100;num=0;while(i<=test){num+=i; i++;}print num;}'
5050

for循环的运用

[root@localhost ~]# awk 'BEGIN{test=0;for(i=0;i<=100;i++){test+=i;}print test;}'
5050

do循环的运用

[root@localhost ~]# awk 'BEGIN{test=0;i=0;do{test+=i;i++}while(i<=100)print test;}'
5050

5.awk的数组运用

awk -F: 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
0 root
1 bin
2 daemon
3 adm
4 lp
5 sync
........................................................................

6.awk字符串函数的运用

函数名 描述
sub 匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的 时候
sub (regular expression, substitution string):
sub (regular expression, substitution string, target string)

实例:

         awk '{ sub(/test/, "mytest"); print }' testfile
         awk '{ sub(/test/, "mytest"); $1}; print }' testfile

第一个例子在整个记录中匹配,替换只发生在第一次匹配发生的时候。如要在整个文件中进行匹配需要用到gsub

第二个例子在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候。

gsub 整个文档中进行匹配

gsub (regular expression, substitution string)

gsub (regular expression, substitution string, target string)

实例:

   awk '{ gsub(/test/, "mytest"); print }' testfile
         awk '{ gsub(/test/, "mytest" , $1) }; print }' testfile

第一个例子在整个文档中匹配test,匹配的都被替换成mytest。

第二个例子在整个文档的第一个域中匹配,所有匹配的都被替换成mytest。

index 返回子字符串第一次被匹配的位置,偏移量从位置1开始
index(string, substring)

实例:

awk '{ print index("test", "mytest") }' testfile

实例返回test在mytest的位置,结果应该是3。

实例

awk '{ print substr( "hello world", 7,11 ) }' 

上例截取了world子字符串。
split 可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割
split( string, array, field separator )
split( string, array )

上例截取了world子字符串。
split 可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割
split( string, array, field separator )
split( string, array )

实例

         awk '{start=match("this is a test",/[a-z]+$/); print start}'
         awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'

实例:

  awk '{start=match("this is a test",/[a-z]+$/); print start}'
         awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'

 

 

 

 

 

 

 

 

 

 

 

### 获取指定进程信息并通过 `awk` 处理输出 在 Linux 或类 Unix 系统中,`pidin` 并不是一个标准命令,它通常出现在 QNX 操作系统中,用于显示进程信息。在标准 Linux 系统中,获取进程信息通常使用 `ps`、`pidof` 或 `/proc` 文件系统。 若目标是在 Linux 环境下获取指定进程 ID 的信息并使用 `awk` 处理输出,可以使用如下方法: #### 使用 `ps` 命令结合 `awk` 提取进程信息 例如,获取名为 `filebeat` 的进程信息,并提取其 PID 和启动时间: ```bash ps -ef | grep filebeat | grep -v grep | awk '{print "PID: " $2, "Start Time: " $5}' ``` 该命令中: - `ps -ef` 显示所有进程的完整信息; - `grep filebeat` 过滤出包含 `filebeat` 的进程; - `grep -v grep` 排除掉 `grep` 自身的进程; - `awk '{print "PID: " $2, "Start Time: " $5}'` 提取 PID 和启动时间字段。 #### 使用 `/proc` 文件系统获取更详细的进程信息 在 `/proc` 目录下,每个运行中的进程都有一个以其 PID 命名的子目录,其中包含该进程的详细信息。例如,查看 PID 为 1234 的进程的状态信息: ```bash cat /proc/1234/status ``` 可以结合 `awk` 来提取特定字段,如进程状态: ```bash awk '$1 == "State:" {print $2}' /proc/1234/status ``` #### 使用 `pidof` 获取进程 ID 并处理 如果已知进程名称,可以使用 `pidof` 获取其 PID,并将其传递给 `awk` 处理: ```bash pidof filebeat | awk '{for(i=1;i<=NF;i++) print "Killing PID: " $i; system("kill -9 " $i)}' ``` 该命令会获取所有 `filebeat` 进程的 PID,并逐个输出并终止进程。 #### 示例脚本:获取并处理进程信息 以下是一个完整的示例脚本,用于获取 `filebeat` 进程的信息,并输出其 PID 和启动时间: ```bash #!/bin/bash ps -ef | grep filebeat | grep -v grep | awk ' { printf("Process Name: %s, PID: %s, Start Time: %s\n", $8, $2, $5) }' ``` 该脚本将输出类似以下内容: ``` Process Name: /usr/bin/filebeat, PID: 1234, Start Time: 10:00 ``` 通过上述方式,可以灵活地获取指定进程的信息,并使用 `awk` 对输出进行格式化和处理。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值