【Shell】awk命令--输出某列,列求和,列求平均值,列最大值,列去重复,取倒列,过滤行,匹配,不匹配,内置变量|定义分隔符|多个分隔符...

本文详细介绍了awk命令的使用,包括基本语法、输出特定列、行处理、运行shell命令、获取特定行和列、过滤、匹配、内置变量等技巧。内容涵盖awk在Linux系统中的应用,如数据处理、文件操作和脚本编写。通过实例展示了awk在处理文本数据时的强大功能,如求和、平均值、最大值、去重和转置等操作。

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

目录

awk基本语法

awk输出某几列

awk遍历文件行处理

awk中运行shell命令

方法1:awk 内置函数system

方法2 通过awk  print 交给bash

awk中运行shell命令并用awk的参数

awk命令获取文本的某一行,某一列

AWK 技巧(取倒列,过滤行,匹配,不匹配,内置变量等)

   通过第一个域找出字符长度为4的

    当第二列值大于3时,创建空白文件,文件名为当前行第一个域$1 (touch $1)

   将文档中 liu 字符串替换为 hong

    求第二列的和

    求第二列的平均值

   求第二列中的最大值

    将第一列过滤重复后,列出每一项,每一项的出现次数,每一项的大小总和

定义分隔符|多个分隔符[]

使用awk取某一行数据中的倒数第N列:$(NF-(n-1))

将每一行中相同第一列对应的其他列进行拼接

Awk取文件中的指定数据

linux文件按大小来排序

awk 获取某些列的某些行(打印或不打印第几行)

awk中的"匹配"与"不匹配"

AWK的内置变量(NF、NR、FNR、FS、OFS、RS、ORS)

AWK对文件的"某一列进行去重"的做法      (命令: awk '{a[$n]=$0}END{for(i in a)print a[i]}' filename)

AWK 将列转为行的做法

shell将多行转为一行(或将多行中的某一列转化为行)的做法

shell去掉最后一个字符的做法


awk基本语法

awk 'BEGIN{//begin code }            pattern1{//pattern1 code}             pattern2{//pattern2 code}          END{//end code }'

BEGIN部分的代码,最先执行

然后循环从管道中读取的每行文本,如果匹配pattern1 ,则执行pattern1 code的代码,匹配pattern2,则执行pattern2 code代码
最后,执行END部分的代码end code

如下所示,分别求奇数行与偶数行的和:
$ seq 1 5
1
2
3
4
5

$ seq 1 5|awk 'BEGIN{print "odd","even"}    NR%2==1{odd+=$0}    NR%2==0{even+=$0}    END{print odd,even}'
odd even
9 6

原文链接:https://blog.youkuaiyun.com/weixin_31201737/article/details/113045998

awk输出某几列


有这样一个文本,需要截取前5列

[root@SH]# cat test.txt 
 2      3651415576       940761              0            0 0000000000000000
 3      3532686312       939551              0            0 0000000000000000
 4      3873453656       984285              0            0 0000000000000000
 5      3884604640       970761              0            0 0000000000000000
 6      2116906224       493295              0            0 0000000000000000
 7      1760674752       480700              0            0 0000000000000000
 8               0            0       29979808         6002 0000000000000000
 10              0            0        3299944         1433 0000000000000000
 11              0            0     2199434640       312565 0000000000000000

方法一:

awk '{print $1,$2,$3,$4,$5}  #(别忘了“,”,否则黏在一起,$1 $2 $3与$1$2$3没什么不同.)

另外一种实现方法awk '{NF-=2}1',这里的1换成别的数字也可以,NF-=2表示倒数第二列
https://my.oschina.net/u/3746745/blog/1923899

linux下统计某个进程的CPU占用和内存使用

#!/bin/bash
# while loop
CpuMemStat=""
datemk=""
while true
do
CpuMemStat=` ps aux |grep -i server |grep redis |grep -v py`
datemk=`date "+%Y-%m-%d %H:%M:%S"`
echo $datemk $CpuMemStat >> result.txt
#echo $datemk $CpuMemStat
sleep 20s
done


上面的遇到CpuMemStat结果是多行的就歇菜了,改成

#!/bin/bash
# while loop 
CpuMemStat=""
datemk=""
CpuMemStat=`ps aux |sed -n '1p'|awk '{print $1,$2,$3,$4,$5}'`
datemk=`date "+%Y-%m-%d %H:%M:%S"`
echo $datemk $CpuMemStat >> result.txt
while true
do
    #CpuMemStat=` ps aux |grep -i redis-server|awk '{print $1,$2,$3,$4,$5}'`
    datemk=`date "+%Y-%m-%d %H:%M:%S"`
ps aux |grep -i redis-server|awk '{print $1,$2,$3,$4,$5}'|while read line
do
 echo $line
 echo $datemk $line >> result.txt
    #echo $datemk $CpuMemStat
done 
    sleep 1s
done
(一行一行读,不能用for 必须用while,因为in操作符以任意空白字符作为分割, 而read line是以回车符作为分割。)

有一文本文件如下,每行有两个字符串/空格分开。


$ cat list.txt 
Gly G
Ala A
Val V
Leu L
Ile I
Phe F


for line in `cat list.txt`
do
echo $line
done


得到结果如下:

Gly
G
Ala
A
Val
V
Leu
L
Ile
I
Phe
F

============
while read line
do 
echo $line
done list.txt

运行得到结果如下:

Gly G
Ala A
Val V
Leu L
Ile I
Phe F

awk遍历文件行处理

awk基本语法如下:

awk 'BEGIN{//begin code }            pattern1{//pattern1 code}             pattern2{//pattern2 code}          END{//end code }'

BEGIN部分的代码,最先执行

然后循环从管道中读取的每行文本,如果匹配pattern1 ,则执行pattern1 code的代码,匹配pattern2,则执行pattern2 code代码
最后,执行END部分的代码end code

如下所示,分别求奇数行与偶数行的和:
$ seq 1 5
1
2
3
4
5

$ seq 1 5|awk 'BEGIN{print "odd","even"}    NR%2==1{odd+=$0}    NR%2==0{even+=$0}    END{print odd,even}'
odd even
9 6

原文链接:https://blog.youkuaiyun.com/weixin_31201737/article/details/113045998

实战:

OSD 删除黑名单的命令是:ceph osd blacklist rm  192.168.31.66:6800/2776253500

OSD 列出黑名单的命令是: ceph osd blacklist ls 

192.168.31.109:6800/3185421984
192.168.31.66:6800/2776253500
192.168.31.109:6800/1802746272
192.168.31.66:6800/3330484028
192.168.31.109:6800/3170500668
192.168.31.66:6849/4132697147
192.168.31.65:6849/579778875

我们需要 遍历黑名单执行 ceph osd blacklist rm  xxxxx

 ceph osd blacklist ls |awk '{system("ceph osd blacklist rm " $1)}'

(ceph osd blacklist rm 不是awk的内置命令,所有用system)

info.txt


 -5        10.47839 root ssdpool                                        
-25        10.47839     rack rack.ssdpool                               
-28         3.49280         host rdma61.ssdpool                         
 18   ssd   0.87320             osd.18              up  1.00000 1.00000 
 21   ssd   0.87320             osd.21              up  1.00000 1.00000 
 24   ssd   0.87320             osd.24              up  1.00000 1.00000 
 28   ssd   0.87320             osd.28              up  1.00000 1.00000 
-31         3.49280         host rdma63.ssdpool                         
 20   ssd   0.87320             osd.20              up  1.00000 1.00000 
 22   ssd   0.87320             osd.22              up  1.00000 1.00000 
 25   ssd   0.87320             osd.25              up  1.00000 1.00000 
 27   ssd   0.87320             osd.27              up  1.00000 1.00000 
-34         3.49280         host rdma64.ssdpool                         
 19   ssd   0.87320             osd.19              up  1.00000 1.00000 
 23   ssd   0.87320             osd.23              up  1.00000 1.00000 
 26   ssd   0.87320             osd.26              up  1.00000 1.00000 
 29   ssd   0.87320             osd.29            down        0 1.00000 

写一个shell脚本 run.sh,我给它参数61(或者63或64), 它就读取host rdma61.ssdpool下面的行文字的第一个字段,并逐一输出log+字段,直至遇到下一个host rdma 停止。

如: run.sh 61

输出:

log18.txt
log21.txt
log24.txt
log28.txt

如: run.sh 63

log20.txt
log22.txt
log25.txt
log27.txt

脚本

awk -v flag=0 '
/host rdma'$1'/ {flag=1; next}
flag == 1 && /host rdma/ {flage=0; exit}
flag == 1 {print "log"$1".txt"}
' info.txt

说明

-v flag=0 # 设置变量flag=0

/host rdma'$1'/ {flag=1; next}                   #匹配到host rdma'$1'执行flag=1; next,netx 表示不匹配本文本行后面的内容,直接跳到下一行文本

flag == 1 && /host rdma/ {flage=0; exit}  #flag == 1 且匹配到host rdma,则执行{flage=0; exit} ,exit 退出结束

flag == 1 {print "log"$1".txt"}                  #flag == 1 且匹配到host rdma,则执行print "log"$1".txt"


原文链接:https://blog.youkuaiyun.com/bandaoyu/article/details/103190949

awk中运行shell命令

有两种方法:

1.awk内置函数system

2.通过awk print出要执行的命令 然后交给/bin/bash 执行

方法1:awk 内置函数system

执行方法  awk ‘BEGIN{system(“shell命令)}’ 就行

[root@CHSHA-CT-WWW-249 ~]# awk ‘BEGIN{system(“hostname”)}’


CHSHA-CT-WWW-249.360buy.com

[root@CHSHA-CT-WWW-249 ~]# awk ‘BEGIN{system(“df -h”)}’


文件系统 容量 已用 可用 已用% 挂载点
/dev/sda1 19G 2.9G 16G 16% /
/dev/sda3 236G 215M 223G 1% /export
tmpfs 16G 0 16G 0% /dev/shm

[root@CHSHA-CT-WWW-249 ~]# awk ‘BEGIN {system(“echo \”input one number:\”"); getline d;print “you input number is”,d}’

input one number:
12
you input number is 12   #这个采用了awk getline取前面的输入

方法2 通过awk  print 交给bash

[root@CHSHA-CT-WWW-249 ~]# awk ‘BEGIN{print “echo”,”cange”}’|sh
cange[root@CHSHA-CT-WWW-249 ~]# awk ‘BEGIN{print “echo”,”cange”|”bash”}’
cange[root@CHSHA-CT-WWW-249 ~]# awk ‘BEGIN{print “df -h”|”bash”}’
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda1 19G 2.9G 16G 16% /
/dev/sda3 236G 215M 223G 1% /export
tmpfs 16G 0 16G 0% /dev/shm
[root@CHSHA-CT-WWW-249 ~]# awk ‘BEGIN{print “hostname”|”bash”}’
CHSHA-CT-WWW-249.360buy.com

可能上面的例子很简单, 确实  但是原理就是这样 可能工作上你们的需求不同 整个过程不可能这么简单 但是按照这种方式进行处理就行 , 例如对一下文件的重命名 那就可以

pirnt  mv  一个原始文件 跟你要改成的文件 交给bash就行了。

[root@CHSHA-CT-WWW-249 test]# ls|awk ‘{print “mv “$0″ A_”$0}’
mv 1.jpp A_1.jpp
mv 2.jpp A_2.jpp
mv 3.jpp A_3.jpp
[root@CHSHA-CT-WWW-249 test]# ls|awk ‘{print “mv “$0″ A_”$0}’|bash
[root@CHSHA-CT-WWW-249 test]# ls
A_1.jpp A_2.jpp A_3.jpp

awk中运行shell命令并用awk的参数

awk '{system(“ls ” $1)'| some.txt

即 sytem()括号内,加双引号的“”看待成shell命令,不加双引号的看待成awk环境变量,system("echo "$1"\"-->\"") shell命令内有双引号的,需要\转译。

ibv_devices

   device                 node GUID
    ------              ----------------
    rocep24s0f2         b69691fffea59b5e
    rocep24s0f1         b69691fffea59b5d
    rocep24s0f3         b69691fffea59b5f
    rocep24s0f0         b69691fffea59b5c

ibv_devices|awk 'BEGIN{ echo "--"}  /rocep/{system("echo "$1"\"-->\"`ls /sys/class/infiniband/"$1"/device/net`")} END{echo "--"}'

rocep24s0f2-->ens2f2
rocep24s0f1-->ens2f1
rocep24s0f3-->ens2f3
rocep24s0f0-->ens2f0

awk命令获取文本的某一行,某一列

1、打印文件的第一列(域)                 : awk '{print $1}' filename
2、打印文件的前两列(域)                 : awk '{print $1,$2}' filename
3、打印完第一列,然后打印第二列  : awk '{print $1 $2}' filename
4、打印文本文件的总行数                : awk 'END{print NR}' filename
5、打印文本第一行                          :awk 'NR==1{print}' filename
6、打印文本第二行第一列                :sed -n "2, 1p" filename | awk 'print $1'

#(获取test文件的第4行)

#cat test| awk 'NR==4'或cat test|sed -n '4p'直接获取某一行的数据
    shell里面的赋值方法有两种,格式为
    1) arg=`(命令)`
    2) arg=$(命令)
因此,如果想要把某一文件的总行数赋值给变量nlines,可以表达为:
    1) nlines=`(awk 'END{print NR}' filename)`
或者

    2) nlines=$(awk 'END{print NR}' filename)

AWK 技巧(取倒列,过滤行,匹配,不匹配,内置变量等)

   wang     4
   cui      3
   zhao     4
   liu      3
   liu      3
   chang    5
   li       2

   通过第一个域找出字符长度为4的


    awk 'length($1)=="4"{print $1}'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值