ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

文本处理之awk基础

2021-05-04 15:01:44  阅读:123  来源: 互联网

标签:读取 基础 文本处理 etc awk print txt root


预定义变量

预定义变量分为两类:控制awk工作的变量和携带信息的变量。

第一类:控制AWK工作的预定义变量
RS :输入记录分隔符,默认为换行符\n ,参考RS
IGNORECASE :默认值为0,表示所有的正则匹配不忽略大小写。设置为非0值(例如1),之后的匹配将忽略
大小写。例如在BEGIN块中将其设置为1,将使FS、RS都以忽略大小写的方式分隔字段或分隔record
FS :读取记录后,划分为字段的字段分隔符。参考FS
FIELDWIDTHS :以指定宽度切割字段而非按照FS。参考FIELDWIDTHS
FPAT :以正则匹配匹配到的结果作为字段,而非按照FS划分。参考FPAT
OFS :print命令输出各字段列表时的输出字段分隔符,默认为空格" "
ORS :print命令输出数据时在尾部自动添加的记录分隔符,默认为换行符\n
CONVFMT :在awk中数值隐式转换为字符串时,将根据CONVFMT的格式按照sprintf()的方式自动转换为字
符串。默认值为"%.6g
OFMT :在print中,数值会根据OFMT的格式按照sprintf()的方式自动转换为字符串。默认值为"%.6g

第二类:携带信息的预定义变量
ARGC 和ARGV :awk命令行参数的数量、命令参数的数组。参考ARGC和ARGV
ARGIND :awk当前正在处理的文件在ARGV中的索引位置。所以,如果awk正在处理命令行参数中的某文件,
则ARGV[ARGIND] == FILENAME 为真
FILENAME :awk当前正在处理的文件(命令行中指定的文件),所以在BEGIN中该变量值为空
ENVIRON :保存了Shell的环境变量的数组。例如ENVIRON["HOME"] 将返回当前用户的家目录
NR :当前已读总记录数,多个文件从不会重置为0,所以它是一直叠加的
  可以直接修改NR,下次读取记录时将在此修改值上自增
FNR :当前正在读取文件的第几条记录,每次打开新文件会重置为0
  可以直接修改FNR,下次读取记录时将在此修改值上自增
NF :当前记录的字段数,参考NF
RT :在读取记录时真正的记录分隔符,参考RT
RLENGTH :match()函数正则匹配成功时,所匹配到的字符串长度,如果匹配失败,该变量值为-1
RSTART :match()函数匹配成功时,其首字符的索引位置,如果匹配失败,该变量值为0
SUBSEP : arr[x,y] 中下标分隔符构建成索引时对应的字符,默认值为\034 ,是一个不太可能出现在字符串中的不可打印字符。参考复杂数组

awk选项、内置变量、内置函数

选项

-e program-text
--source program-text
指定awk程序表达式,可结合-f选项同时使用
在使用了-f选项后,如果不使用-e,awk program是不会执行的,它会被当作ARGV的一个参数
-f program-file
--file program-file
从文件中读取awk源代码来执行,可指定多个-f选项
-F fs
--field-separator fs
指定输入字段分隔符(FS预定义变量也可设置)
-n
--non-decimal-data
识别文件输入中的8进制数(0开头)和16进制数(0x开头)
echo '030' | awk -n '{print $1+0}'
-o [filename]
格式化awk代码。
不指定filename时,则默认保存到awkprof.out
指定为`-`时,表示输出到标准输出
-v var=val
--assign var=val
在BEGIN之前,声明并赋值变量var,变量可在BEGIN中使用

读取文件的几种方式:

1,按字符数量读取:每一次可以读取一个字符,或者多个字符,直到把整个文件读取完
  while read -n 1 char;do echo $char;done < a.txt
2,按照分隔符进行读取:一直读取直到遇到分隔符才停止,下次继续从分隔的位置处向后读取,直到读完整个文件
  while read -d "m" chars;do echo "$chars";done < a.txt
3,按行读取:每次读取一行,直到把整个文件读完
  是按照分隔符读取的一种特殊情况:将分隔符指定为了换行符\n
  while read line;do echo "$line";done < a.txt
4,一次性读取整个文件
  是按字符数量读取的特殊情况,也是按分隔符读取的特殊情况
  read -N 10000000 data < a.txt
  read -d '_' data < a.txt
5,按字节数量读取

awk用法入门

awk 'awk_program' a.txt

1)a.txt是awk要读取的文件,可以是0个文件或一个文件,也可以多个文件

如果不给定任何文件,但又需要读取文件,则表示从标准输入中读取

2)单引号包围的是awk代码,也称为awk程序
尽量使用单引号,因为在awk中经常使用$符号,而$ 符号在shell是变量符号,如果使用双引号包围awk代码,则 符 号 会 被 s h e l l 解 析 成 s h e l l 变 量 , 然 后 进 行 s h e l l 变 量 替 换 。 使 用 单 引 号 包 围 a w k 代 码 , 则 符号会被shell解析成shell变量,然后进行shell变量替换。使用单引号包围awk代码,则 符号会被shell解析成shell变量,然后进行shell变量替换。使用单引号包围awk代码,则 会脱离shell的魔掌,使得$ 符号留给了awk去解析

3)awk程序中,大量使用大括号,大括号表示代码块,代码块中间可以之间连用,代码内部的多个语句需使用分号“;” 分隔。

awk '{print $0}' a.txt
awk '{print $0}{print $0;print $0}' a.txt

BEGIN和END语句块

awk 'BEGIN{print "我在前面"}{print $0}' a.txt
awk 'END{print "我在后面"}{print $0}' a.txt
awk 'BEGIN{print "我在前面"}{print $0}END{print "我在后面"}' a.txt

BEGIN代码块:

在读取文件之前执行,且执行一次
在BEGIN代码块中,无法使用$0或其他一些特殊变量

END代码块:

在读取文件完成之后执行,且执行一次
有END代码块,必有要读取的数据(可以是标准输入)
END代码块中可以使用$0等一些特殊变量,只不过这些特殊变量保存的是最后一轮awk循环的数据

main代码块:

读取文件时循环执行,(默认情况)每读取一行,就执行一次main代码块
main代码块可有多个

awk命令行结构和语法结构

在shell命令行当中,双短横线–表示选项到此结束,后面的都是命令的参数

awk [ -- ] program-text file ...
awk -f program-file [ -- ] file ...
awk -e program-text [ -- ] file ...

cmd -x -r root -ppassword a.txt b.txt c.txt
  1,选项分为长选项和短选项
  2,选项分为3种:
    1)不带参数的选项
    2)是带参数的选项,如果该选项后面没有给参数,则报错
    3)参数可选的选项,选项后面可以跟参数,也可以不跟参数
      参数可选选项,如果要接参数,则必须将参数紧紧跟在选项后面,不能使用空格分隔选项和参数
  3,两种参数:
    1)选项型参数
    2)非选项型参数

范例:awk的语法充斥着pattern{action}的模式,它们称为awk rule:awk语句块可划分如下

awk 'BEGIN{n=3} /^[0-9]/$1>5{$1=333;print $1}  /Alice/{print "Alice"} END{print "hello"}' a.txt
1)pattern部分用于测试筛选数据,action表示在测试通过后执行的操作
2)pattern和action都可以省略
  省略pattern,等价于对每个一行数据都执行action
    awk '{print $0}' a.txt
  省略代码块{action},等价于{print}即输出所有行
    awk '/Alice/' a.txt 等价于 awk '/Alice/{print $0}' a.txt
  省略代码块中的action,表示对筛选的行什么都不做
    awk '/Alice/{}' a.txt
  parttern{action}任何一部分都可以省略
    awk '' a.txt
  多个pattern{action}可以直接连接连用
  action中多个语句连用需使用分号分隔

pattern和action

对于pattern{action}语句结构(都称之为语句块),其中的pattern部分可以使用下面列出的模式

# 特殊pattern
BEGIN
END

# 布尔代码块
/regulat expression/    # 正则匹配成功与否/a.*ef/{action}
relational expression   # 即等值比较,大小比较 3>2{action}
pattern && pattern      # 逻辑与3>2 && 3>1 {action}
pattern || pattern      # 逻辑或 3>2 || 3<1 {action}
! pattern               # 逻辑取反 !/a.*ef/{action}
(pattern)               # 改变优先级
pattern ? pattern : pattern  # 三目运算符决定的布尔值
# 范围pattern,非布尔代码块
pattern1,pattern2      # 范围,pat1打开,pat2关闭,即flip,flop模式

action部分,可以是任何语句,例如print语句。

awk读取文件

详细分析awk如何读取文件

awk读取输入文件时,每次读取一条记录(record)(默认情况下按行读取,所以此时记录就是行)。每读取一条记录,将其保存到 $0中,然后执行一次main代码段

awk '{print $0}' a.txt

如果是空文件,则因为无法读取到任何一条记录,将导致直接关闭文件,而不会进入main代码段。

touch x.log   # 创建一个空文件
awk '{print "holle word"}' x.log

可设置表示输入记录分隔符的预定义变量RS(Record Separator)来改变每次读取的记录模式。

# RS="\n" , RS="m"
awk 'BEGIN{RS="\n"}{print $0}' a.txt
awk 'BEGIN{RS="m"}{print $0}' a.txt

RS通常设置在BEGIN代码块中,因为要先于读取文件就确定好RS分隔符

RS指定输入记录分隔符时,所读取的记录中是不包含分隔符字符的。例如RS="a",则$0 中一定不可能出现字符a。

RS两种可能情况:

RS为单个字符:直接使用该字符来分割记录
RS为多个字符:将其当做正则表达式,只要匹配正则表达式的符号,都用来分割记录
  设置预定义变量IGNORECASE为非零值,正则匹配时表示忽略大小写
  兼容模式下,只有首字符才生效,不会使用正则模式去分割记录

特殊的RS值用来解决特殊读取需求:

RS="":按段落读取
RS="\0":一次性读取所有数据,但有些特殊文件中包含了空字符\0
RS="^$":真正的一次性读取所有数据,因为非空文件不可能匹配成功
RS="\n+":按行读取,但忽略所有空行
按段落读取:RS=''
awk 'BEGIN{RS=''}{print $0"------""}' a.txt

#一次性读取所有数据:RS='\0' RS="^$"
awk 'BEGIN{RS='\0'}{print $0"------""}' a.txt
awk 'BEGIN{RS='^$'}{print $0"------"}' a.txt

# 忽略空行:RS='\n+'
awk 'BEGIN{RS='\n+'}{print $0"------""}' a.txt

# 忽略大小写:预定义变量IGNORECASE设置为非0值
awk 'BEGIN{IGNORECASE=1}{print $0"------"}' RS='[ab]' a.txt
预定义变量RT:
在awk每次读完一条记录时,会设置一个称为RT的预定义变量,表示Record Termination。
当RS为单个字符时,RT的值和RS的值是相同的。
当RS为多个字符(正则表达式)时,则RT设置为正则匹配到记录分隔符之后,真正用于划分记录时的字符。
当无法匹配到记录分隔符时,RT设置为控制空字符串(即默认的初始值)。
awk 'BEGIN{RS="(fe)?male"}{print RT}' a.txt

两种行号:NR和FNR

在读取每条记录之后,将其赋值给$0,同时还会设置NR,FNR,RT。

NR:所有文件的行号计数器
FNR:是各个文件的行号计数器

awk '{print NR}' a.txt b.txt
awk '{print FNR}' a.txt b.txt

详细分析字段分割

awk读取每一条记录之后,会将其赋值给$0,同时还会对这条记录按照预定义变量 FS划分字段,将划分好的各个字段分别赋值给$1,$2, 3... 3... 3...n,同时将划分的字段数量赋值给预定义变量NF

引用字段的方式

$N 引用字段:

  N=0:即$0,引用记录本身
  0<N<=NF:引用对应字段
  N>NF:表示引用不存在的字段,返回空字符串
  N<0:报错

可使用变量或计算的方式指定要获取的字段序号。

awk '{n = 5;print $n}' a.txt
awk '{print $(2+2)}' a.txt    # 括号必不可少,用于改变优先级
awk '{print $(NF-3)}' a.txt
分割字段的方式

读取record之后,将使用预定义变量 FS,FILEDWIDTHHS或FPAT中的一种来分割字段。分割完成之后,再进入main代码段(所以,在main中设置FS对本次已经读取的record是没有影响的,但会影响下次读取)

FS或 -F

FS 或者 -F:字段分隔符
  Fs为单个字符时,该字符即为字段分隔符
  FS为多个字符时,则采用正则表达式模式作为字段分隔符
  特殊的,也是FS默认的情况,FS为单个空格时,将以连续的空白(空格,制表符,换行符)作为字段分隔符
  特殊的,FS为空字符串""时,将对每个字符都进行分隔,即每个字符都作为一个字段
  设置预定义变量IGNORECASE为非零值,正则匹配时表示忽略大小写(只影响正则,所以FS为单字时无影响)
  如果record中无法找到FS指定的分隔符(例如将FS设置为"\n"),则整个记录作为一个字段,即$1 和$0 相等。

范例:
面试题:取出分区利用率

[20:41:33 root@Bj-Ubuntu ~]# df | awk '{print $1,$5}'
Filesystem Use%
udev 0%
tmpfs 6%
/dev/sda2 14%
tmpfs 0%
tmpfs 0%
tmpfs 0%
/dev/loop0 100%
/dev/loop1 100%
/dev/sda3 1%
tmpfs 0%
[20:42:06 root@Bj-Ubuntu ~]# df | awk -F"[[:space:]]+|%" '{print $5}'
Use
0
6
14
0
0
0
100
100
1
0

[root@longwang ~]# df | awk -F"[ %]+" '{print $5}'
Use
0
0
10
0
10
1
16
0
[root@longwang ~]# df | awk -F"[ %]+" '{print $1,$5}'
Filesystem Use
devtmpfs 0
tmpfs 0
tmpfs 10
tmpfs 0
/dev/mapper/cl-root 10
/dev/mapper/cl-data 1
/dev/sda1 16
tmpfs 0

范例

[root@VM_0_10_centos ~]# awk -F'[[ ]' '{print $1,$5}'
/apps/nginx/logs/nginx.access.log | head -n3
58.87.87.99 09/Jun/2020:03:42:43
128.14.209.154 09/Jun/2020:03:42:43
64.90.40.100 09/Jun/2020:03:43:11

取ip地址centos6

[06:47:47 root@centos6 ~]# ip a |awk -F"[ /]+" '/inet / && !/127/{print $3}'
172.31.0.10

ubuntu

[20:43:38 root@Bj-Ubuntu ~]# ip a |awk -F"[ /]+" '/inet / && !/127/{print $3}'
172.31.0.19

centos8

[root@longwang ~]# ip a | awk -F"[ /]+" '/inet / && !/127/{print $3}'
172.31.0.38

面试题:文件host_list.log 如下格式,请提取”.magedu.com”前面的主机名部分并写入到回到该文件中

[root@longwang ~]# cat host_list.log 
1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
[root@longwang ~]# awk -F"[ .]" '{print $2}' host_list.log 
www
blog
study
linux
python
[root@longwang ~]# awk -F"[ .]" '{print $2}' host_list.log >> host_list.log 
[root@longwang ~]# cat host_list.log 
1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
www
blog
study
linux
python

常见的内置变量

FS:输入字段分隔符,默认为空白字符,功能相当于 -F

范例

[root@longwang ~]# awk -v FS=':' '{print $1,FS,$3}' /etc/passwd
root : 0
bin : 1
daemon : 2
adm : 3

[root@longwang ~]# awk -v FS=":" '{print $1FS$3}' /etc/passwd
root:0
bin:1
daemon:2
[root@longwang ~]# awk -F: '{print $1,$3,$7}' /etc/passwd
root 0 /bin/bash
bin 1 /sbin/nologin
daemon 2 /sbin/nologin

[root@longwang ~]# S=;awk -v FS=$S '{print $1FS$3}' /etc/passwd
ro
bn
de
am

[root@longwang ~]# awk -v FS=":" '{print $1FS$3}' /etc/passwd | head -n3
root:0
bin:1
daemon:2
[root@longwang ~]# S=:;awk -F$S '{print $1,$3}' /etc/passwd | head -n3
root 0
bin 1
daemon 2
#-F 和 FS变量功能一样,同时使用会冲突
[root@longwang ~]# awk -v FS=":" -F";" '{print $1FS$3}' /etc/passwd | head -n3
root:x:0:0:root:/root:/bin/bash;
bin:x:1:1:bin:/bin:/sbin/nologin;
daemon:x:2:2:daemon:/sbin:/sbin/nologin;
[root@longwang ~]# awk -F";" -v FS=":" '{print $1FS$3}' /etc/passwd | head -n3
root:0
bin:1
daemon:2
#-F 和 FS变量功能一样,同时使用会 -F 优先级高
[root@longwang ~]# awk -v FS=":" -F";" '{print $1}' /etc/passwd | head -n3
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@longwang ~]# awk -v FS=";" -F":" '{print $1}' /etc/passwd | head -n3
root
bin
daemon

OFS:输出字段分隔符,默认为空白字符

[root@longwang ~]# awk -v FS=':' '{print $1,$3,$7}' /etc/passwd | head -n1
root 0 /bin/bash
[root@longwang ~]# awk -v FS=":" -v OFS=':' '{print $1,$3,$7}' /etc/passwd | head -n1
root:0:/bin/bash

RS:输入记录record分隔符,指定输入时的换行符

[root@longwang ~]# awk -v RS=' ' '{print }' /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
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP
User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel
Overflow

ORS:输出记录分隔符,输出时用指定符号代替换行符

[root@longwang ~]# awk -v RS=' ' -v ORS='###' '{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

NF:字段数量

#引用变量时,变量前不需加$
[root@longwang ~]# awk -F: '{print NF}' /etc/passwd
7
7
[root@longwang ~]# awk -F: '{print $(NF-1)}' /etc/passwd
/root
/bin
/sbin

面试题:接数最多的前3个IP

172.20.65.65 - - [24/May/2018:10:13:20 +0800] "GET /centos/6/Packages/python-iwlib-0.1-1.2.el6.x86_64.rpm HTTP/1.1" 200 14724 "-" "CentOS (anaconda)/6.9"
172.20.65.65 - - [24/May/2018:10:13:20 +0800] "GET /centos/6/Packages/hplip-common-3.14.6-4.el6.1.x86_64.rpm HTTP/1.1" 200 81384 "-" "CentOS (anaconda)/6.9"
172.20.65.65 - - [24/May/2018:10:13:20 +0800] "GET /centos/6/Packages/sane-backends-libs-gphoto2-1.0.21-5.el6.x86_64.^C
[root@longwang ~]# awk -F" +|:" '{print $1}' access_log | sort | uniq -c | sort -nr | head -n3
   4870 172.20.116.228
   3429 172.20.116.208
   2834 172.20.0.222
  
[root@iZwz98 ~]# ss -tn
State       Recv-Q Send-Q Local Address:Port                Peer Address:Port              
ESTAB       0      52     172.18.106.169:8222               114.246.99.151:51006              
ESTAB       0      0      172.18.106.169:44128              100.100.30.26:80                 
ESTAB       0      0      172.18.106.169:8222               118.126.89.216:50034              
[root@iZwz98 ~]# ss -tn | grep "^ESTAB" | awk -F"[[:space:]]+|:" '{print $(NF-2)}'
114.246.99.151
100.100.30.26
[root@iZwz98 ~]# ss -tn | awk -F"[[:space:]]+|:" '/^ESTAB/{print $(NF-2)}'
114.246.99.151
100.100.30.26
58.33.35.82

范例:每十分钟检查将连接数超过100个以上的IP放入黑名单拒绝访问

[root@iZwz98 ~]# vim deny_dos.sh
#!/bin/bash
LINK=100
while true;do
    ss -tn | awk -F"[[:space:]]+|:" '/^ESTAB/{print $(NF-2)}' |sort  | uniq -c | while read count ip ;do
        if [ $count -gt $LINK ];then
            iptables -A INPUT -s $ip -j REJECT
        fi
    done
done

[root@iZwz98 ~]# chmod +x deny_dos.sh 
[root@iZwz98 ~]# crontab -e
[root@iZwz98 ~]# crontab -l
*/10 * * * * /root/deny_dos.sh

NR:记录的编号

[root@longwang ~]# awk '{print NR,$0}' /etc/issue /etc/centos-release
1 \S
2 Kernel \r on an \m
3 
4 CentOS Linux release 8.1.1911 (Core) 

范例:取ifconfig输出结果中的IP地址

[root@CentOS-8 ~]# ifconfig eth0 | awk '/netmask/{print $2}'
172.31.0.20
[root@CentOS-8 ~]# ifconfig eth0 | awk 'NR==2{print $2}'
172.31.0.20

范例:

[root@CentOS-8 ~]# awk -F: '{print NR}' /etc/passwd
1
2
3
...
45
[root@CentOS-8 ~]# awk -F: 'END{print NR}' /etc/passwd
45
[root@CentOS-8 ~]# awk -F: 'BEGIN{print NR}' /etc/passwd
0

FNR:各文件分别计数,记录的编号

[root@CentOS-8 ~]# awk  '{print FNR}' /etc/fstab /etc/inittab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@CentOS-8 ~]# awk '{print NR,$0}' /etc/issue /etc/redhat-release 
1 \S
2 Kernel \r on an \m
3 
4 CentOS Linux release 8.1.1911 (Core)
[root@CentOS-8 ~]# awk  '{print FNR,$0}' /etc/issue /etc/redhat-release 
1 \S
2 Kernel \r on an \m
3 
1 CentOS Linux release 8.1.1911 (Core)

FILENAME:当前文件名

[root@CentOS-8 ~]# awk '{print FILENAME}' /etc/fstab 
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
[root@CentOS-8 ~]# awk '{print FNR,FILENAME,$0}' /etc/issue /etc/redhat-release 
1 /etc/issue \S
2 /etc/issue Kernel \r on an \m
3 /etc/issue 
1 /etc/redhat-release CentOS Linux release 8.1.1911 (Core)

ARGC:命令行参数的个数

[root@CentOS-8 ~]# awk '{print ARGC}' /etc/issue /etc/redhat-release 
3
3
3
3
[root@CentOS-8 ~]# awk 'BEGIN{print ARGC}' /etc/issue /etc/redhat-release 
3

ARGV:数组,保存的是命令行所给定的各参数,每一个参数:ARGV[0],…

[root@CentOS-8 ~]# awk 'BEGIN{print ARGV[0]}' /etc/issue /etc/redhat-release 
awk
[root@CentOS-8 ~]# awk 'BEGIN{print ARGV[1]}' /etc/issue /etc/redhat-release 
/etc/issue
[root@CentOS-8 ~]# awk 'BEGIN{print ARGV[2]}' /etc/issue /etc/redhat-release 
/etc/redhat-release
[root@CentOS-8 ~]# awk 'BEGIN{print ARGV[3]}' /etc/issue /etc/redhat-release 

自定义变量

自定义变量是区分字符大小写的,使用下面方式进行赋值

-v var=value
在program中直接定义

范例:

[root@CentOS-8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{print test1,test2}'
test2=hello,gawk
[root@C[root@CentOS-8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{test1=test2="hello,gawk";print test1,test2}'
hello,gawk hello,gawkentOS-8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{test1=test2="hello,gawk";print test1,test2}'
hello,gawk hello,gawk
[root@CentOS-8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{test1=test2="hello,gawk";print test1,test2}'
hello,gawk hello,gawk

范例:

[root@CentOS-8 ~]# awk -v test='hello gawk' '{print test}' /etc/fstab
[root@CentOS-8 ~]# awk -v test='hello gawk' 'BEGIN{print test}'
[root@CentOS-8 ~]# awk 'BEGIN{test="hello,gawk";print test}'
[root@CentOS-8 ~]# awk -F: '{sex="male";print $1,sex,age;age=18}' /etc/passwd
[root@CentOS-8 ~]# cat awkscript
{print script,$1,$2}
[root@CentOS-8 ~]# awk -F: -f awkscript script="awk" /etc/passwd

BEGIN/END模式

BEGIN{}:仅在开始处理文件中的文本之前执行一次

END{}:仅在文本处理完成之后执行一次

动作 printf

printf 可以实现格式化输出

printf “FORMAT”, item1, item2, ...

说明:
必须指定FORMAT

不会自动换行,需要显式给出换行控制符 \n

FORMAT中需要分别为后面每个item指定格式符

格式符:与item一一对应

%s:显示字符串
%d, %i:显示十进制整数
%f:显示为浮点数
%e, %E:显示科学计数法数值
%c:显示字符的ASCII码
%g, %G:以科学计数法或浮点形式显示数值
%u:无符号整数
%%:显示%自身

修饰符

#[.#] 第一个数字控制显示的宽度;第二个#表示小数点后精度,如:%3.1f
- 左对齐(默认右对齐) 如:%-15s
+ 显示数值的正负符号 如:%+d

范例:

awk -F: '{printf "%s",$1}' /etc/passwd
awk -F: '{printf "%s\n",$1}' /etc/passwd
awk -F: '{printf "%20s\n",$1}' /etc/passwd
awk -F: '{printf "%-20s\n",$1}' /etc/passwd
awk -F: '{printf "%-20s %10d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %s\n",$1}' /etc/passwd
awk -F: '{printf “Username: %sUID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %25sUID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %-25sUID:%d\n",$1,$3}' /etc/passwd

标签:读取,基础,文本处理,etc,awk,print,txt,root
来源: https://blog.csdn.net/qq_38419276/article/details/116400792

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有