python,awk,shell格式化输出内容全解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python,awk,shell格式化输出内容全解相关的知识,希望对你有一定的参考价值。

参考技术A 话不多说,直接开始

eg:

echo "Linux" | awk 'printf "|%-15s|\n",$1'
|Linux |

说明:对于echo命令的输出,Linux是经管道发给awk。printf函数包含一个控制串。百分号让printf做好准备,它要打印一个占15个格、向左对齐的字符串,这个字符串夹在两个竖杠之间,并且以换行符结尾。百分号后的短划线表示左对齐。控制串后面跟了一个逗号和$1。printf将根据控制串中的格式说明来格式化字符串Linux。

echo "Linux" | awk 'printf "|%15s|\n",$1'
| Linux|

说明:字符串Linux被打印成一个占15 格、向右对齐的字符串,夹在两个竖杠之间,以
换行符结尾。

cat employees
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500

awk 'printf "The name is: %-15s ID is %8d\n", 3' employees
The name is Tom ID is 4424
The name is Mary ID is 5346
The name is Sally ID is 1654
The name is Billy ID is 1683

说明:要打印的字符串放置在两个双引号之间。第一个格式说明符是%-15s,它对应的参数是$1,紧挨着控制串的右半边引号后面的那个逗号。百分号引出格式说明:短划线表示左对齐,15s表示占15格的字符串。这条命令用来打印一个左对齐、占15格的字符串,后面跟着字符串的ID和一个整数。

echo -e识别转义和特殊意义的符号,如换行符、n、制表符\t、转义符\等。
[root@xuexi tmp]# echo 'Hello World!\n';echo "Hello World"!
Hello World!\n
Hello World!
[root@xuexi tmp]# echo -e 'Hello World!\n';echo "Hello World"!
Hello World!

Hello World!

printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

运行
姓名 性别 体重kg
郭靖 男 66.12
杨过 男 48.65
郭芙 女 47.99
%s %c %d %f都是格式替代符

%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

%-4.2f 指格式化为小数,其中.2指保留2位小数。
eg:
printf "%d %s\n" 1 "abc"
printf %s abcdef
printf %s abc def
printf "%s %s %s\n" a b c d e f g h i j
等等等等
希望大家了解一下

shell法宝之awk,教你如何熟练掌握文件内容的输出和搜索

一、概述

原理

  • 逐行读取文本,默认是用空格键或 “ tab ” 键为分隔符进行分隔
  • 将分隔所得的各个字段都保存到内建变量中,并按模式或者条件执行编辑命令
  • 与sed编辑器类似

特点

  • sed命令通常用于一个整行的处理,awk则是倾向于将一整行分成多个“字段”,然后再进行处理

  • awk信息的读入是逐行读取的,执行结果可以通过 print 的功能将字段打印出来

  • 在使用awk命令的过程中,可以用逻辑操作符号表示以下功能

逻辑操作符代表
&&
丨丨
+
-
*
/
^取余和乘方

二、awk命令

2.1 格式

awk 选项 '模式或条件 {操作}' 文件1 文件2
或
awk -f 脚本文件 文件1 文件2

2.2 常见变量

变量名作用
FS列分割符,指定每行文本的字段分隔符,默认是空格或制表位,和 “-F” 一样
NE当前处理的行的字段个数
NR当前处理的行的行号(序数)
$0当前处理的行的整行内容
$n当前处理行的第n个字段(第n列)
FILENAME被处理的文件名
RS行分隔符,awk文件读取资料时,根据RS的定义来分割成多条记录,而awk一次仅读入一条记录,以进行处理,预设值是 “ \\n ”

三、测试

3.1 简易文本输出测试

  • 输出全部内容
# 功能一样,$0单独使用时可不添加
awk '{print}' cc.txt
awk '{print $0}' cc.txt 

A
B
C
D
E
F
G
H
111
222
333
  • 输出范围行数
  • 共两种方式,功能一样
awk 'NR==1,NR==5 {print}' cc.txt 			# “==”表示等于,NR为当前行数

awk '(NR>=1)&&(NR<=5) {print}' cc.txt 		# >=,<= 同样代表一定范围行,中间需要使用&&连接
A
B
C
D
E
  • 输入指定行数
  • 使用||指定输出所需行数
awk 'NR==1||NR==5 {print}' cc.txt 		# ||表示或
A
E
  • 输出奇偶行
  • 当前行取余等于1则是奇数,0则是偶数
awk '(NR%2)==1 {print}' cc.txt 			# 奇数行
A
C
E
G
111
333

awk '(NR%2)==0 {print}' cc.txt 			# 偶数行
B
D
F
H
222
  • 输出需求开头或者结尾的行
  • 与sed一样,^代表开头,$代表结尾
awk '/^4/ {print}' cc.txt 			# 4开头的行
4D
awk '/Z$/ {print}' cc.txt 			# Z结尾的行
111Z

3.2 BEGIN

BEGIN 模式表示,在处理指定的文本之前,需要先执行此模式中指定的动作, awk 在处理指定的文本,之后再执行 END 模式中指定的动作,END{ } 语句中,一般都会放打印结果等语句

举列

  • 筛选出passwd文件内已 /bin/bash 结尾的行数
  • \\表示转义,否则 /bin 无法查找到
awk 'BEGIN {x=0};/\\/bin\\/bash$/{x++};END {print x}' passwd 
16

3.3 输出特殊字段

  • 输出每行中第一个字段
  • 这里需要使用 -F 把文本内每行字段之间的 " : " 指定出来
awk -F ":" '{print $1}' passwd 		# 打印第一个字段
root
bin
daemon
adm
lp
sync
shutdown
halt
  • 输出每行的第1和第3字段
  • 和前面一样,加个 $3 即可
awk -F ":" '{print $1,$3}' passwd 			# 默认输出出来的都是以空格做分隔
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
  • 基于上面例题,再增加一条要求第三段数值小于10的行
awk -F ":" '$3<10{print $1,$3}' passwd 			# 添加个$3<10即可
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
  • 再做改进,单独输出第三段数值大于1000的行
  • 大于也就是不小于,使用!
  • BEGIN命令也可使用,先处理BEGIN,再处理后面的
awk -F ":" '!($3<1000){print $3}' passwd		# 使用!别忘了用()将内容合并一起
65534
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

awk 'BEGIN {FS=":"};{if($3>=1000){print}}' passwd 		# 此命令也可以
  • 给每行添加序号
awk -F ":" '{print NR,$0}' passwd 		# 每处理完一条,NR值加1
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
...
57 ccaadd:x:1014:1014::/home/ccaadd:/bin/bash
  • 输出 /bash 结尾行的第一段内容
awk -F ":" '$7~"/bash"{print $1}' passwd 		# 先搜索/bash结尾的行,然后打印出第一段
root
dcc
123456
ccd
ddccdd
dccccccc
ccccc
ccaa
ccaacc
dcc666
ccaz
ssassa
33333
1212313
465456465
ccaadd
  • 输出第一段是root开头,而且还需要共七段,并且只输出其中的第1.2段
awk -F ":" '($1~"root")&&(NF==7){print $1,$2}' passwd  		# 按照顺序搜索
root x
  • 输出第七段不是/bin/bash 也不是 /sbin/nologin 的行
awk -F ":" '!($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' passwd 	# 两个选项放一起使用&&
root:x:0:0:root:/root:/bin/bash
dcc:x:1000:1000:dcc:/home/dcc:/bin/bash
123456:x:1001:1001::/home/123456:/bin/bash
ccd:x:1002:1002::/home/ccd:/bin/bash
ddccdd:x:1003:1003::/home/ddccdd:/bin/bash
...

三元运算符使用

  • 例图
    在这里插入图片描述
  • 需求
    • 要求输出这两列中字符大的数值
    • 如果第三个字段的值大于第四个字段,则把第三字段值赋给max,反之则把第四段值赋给max
awk -F ":" '{max=($3>=$4)?$3:$4;{print max}}' passwd
0
1
2
4
7
5
6
7
12
11

3.4 配合shell命令使用

  • 统计PATH中,以 “ : ” 分隔的段落数
echo $PATH | awk 'BEGIN{RS=":"};END{print NR}'		# END最后最后执行
5
  • 统计 bash 用户的个数
  • 配合管道符合,使用 wc -l 命令
awk -F ":" '/bash$/{print | "wc -l"}' passwd 
16
  • 查看系统内存使用比
  • free -m查看系统内存
  • 搜索出Mem这一行,然后使用第三段除以第三+四段(总内存)
  • 乘100加上% 更直观
free -m | awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'
22%
  • 查看CPU的空闲率
  • top -b -n 1 查看本机进程信息
  • 使用 grep 搜索出 cpu 这一行
  • $4 晒出第四段
  • $1 输出第一段,并且加上一个% 直观些
top -b -n 1 | grep Cpu | awk -F "," '{print $4}' | awk '{print $1"%"}'
100.0%
  • 显示上次系统重启的时间
  • second ago 表示显示多少秒前的时间
  • %F %H:%M:%S 表示时间格式,年月日秒
date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"
2021-05-17 02:48:29

3.5 getline

  • 当 getline 左右没有重定向符 “ < ” 或 “ | ” 时,awk就会先读取第一行,然后 geline ,就到第二行。因为 getline 之后,awk 会改变对应的 NF,NR,FNR 和 $0 等内部变量,所以此时的 $0 的值就不是1,而是2了
  • 当 getline 左右有重定向符时,getline 则作用于定向输入文件,由于该文件是刚打开,并没有被 awk 读入一行,只是 getline 读入,那么 getline 返回的是该文件的第一行,而不是隔行

举列

  • seq 10 输出的是1-10行
  • 先由awk获取第一行,然后getline获取第二行,反复进行后,得到的结果如下
seq 10 | awk '{getline;print $0}'
2
4
6
8
10
  • 反过来则是,print $0先读取了awk读取的第一行
  • getline读取2,但是不打印,反复循环,结果如下
seq 10 | awk '{print $0;getline}'
1
3
5
7
9

3.6 OFS

OFS:输出的分隔符

举列

  • OFS表示输出的分隔符为 “ | ”
  • $1=$1 用来激活$0的赋值
  • 通常会在改变OFS后面需要输出$0时才要求重新激活
echo "A B C D" | awk '{OFS="|";print $0;$1=$1;print $0}'
A B C D
A|B|C|D

3.7 awk与数组

  • 设置下标0 1的值,打印出对应结果
awk 'BEGIN{a[0]=10;a[1]=20; print a[1]}'		# 输出下标1
20
awk 'BEGIN{a[0]=10;a[1]=20; print a[0]}'		# 输出下标2
10
  • 同样设置,将下标改为英文字母
awk 'BEGIN{a["abc"]=10;a["def"]=20; print a["abc"]}'		# 英文字母需要使用 “”
10
awk 'BEGIN{a["abc"]=10;a["def"]=20; print a["def"]}'
20
  • 设置循环打印
awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a){print i,a[i]}}'
0 10
1 20
2 30

BEGIN中的命令只能执行一次
awk数组的下标除了数字还可以使用字符串,不过字符串需要 “”

以上是关于python,awk,shell格式化输出内容全解的主要内容,如果未能解决你的问题,请参考以下文章

shell法宝之awk,教你如何熟练掌握文件内容的输出和搜索

shell三剑客之awk

shell脚本之awk工具的使用

Shell编程之正则表达式三剑客——awk工具

Shell编程之正则表达式

shell七之awk的用法