Shell ❀ 三剑客 - Grep + Sed + Awk

2023-05-16

文章目录

  • 八、三剑客 - Grep + Sed + Awk
    • 1、Grep - 过滤
      • 1.1 常用grep参数
      • 1.2 使用方法
    • 2、Sed - 行匹配
      • 2.1 执行原理
      • 2.2 常见语法
      • 2.3 使用方法
        • 2.3.1 地址边界的设定
        • 2.3.2 基础编辑命令
        • 2.3.3 扩展操作
        • 2.3.4 命令执行案例
    • 3、Awk - 列匹配
      • 3.1 awk能做什么
      • 3.2 执行原理
      • 3.3 命令的使用
      • 3.4 语法格式与使用
        • 3.4.1 输出方式
          • 3.4.1.1 print的使用格式与参数
          • 3.4.1.2 printf的使用格式与参数
          • 3.4.1.3 重定向操作
        • 3.4.2 变量操作
          • 3.4.2.1 记录变量
          • 3.4.2.2 数据变量
          • 3.4.2.3 自定义变量
          • 3.4.2.4 常见操作符号
          • 3.4.2.5 常见模式
          • 3.4.2.6 模式类型
          • 3.4.2.7 Action类型
          • 3.4.2.8 控制语句
          • 3.4.2.9 数组操作
          • 3.4.2.10 内置函数

八、三剑客 - Grep + Sed + Awk

1、Grep - 过滤

grep家族分为grepegrepfgrep,根据用户指定的过滤条件对目标文件进行逐行匹配检查,打印出符合条件的行,即文本搜索工具;

  • grep:支持使用基本正则表达式;
  • egrep:支持使用扩展正则表达式;
  • fgrep:不支持使用正则表达式;
# 给grep家族加上特定颜色
[root@localhost shell]# alias | grep grep
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias xzegrep='xzegrep --color=auto'
alias xzfgrep='xzfgrep --color=auto'
alias xzgrep='xzgrep --color=auto'
alias zegrep='zegrep --color=auto'
alias zfgrep='zfgrep --color=auto'
alias zgrep='zgrep --color=auto'

# 修改系统语言为英文
[root@localhost shell]# cat /etc/locale.conf 
LANG="en_US.UTF-8"

1.1 常用grep参数

  • -n :显示行号;
  • -o :只显示匹配的内容;
  • -q :静默模式,没任何输出,需要用echo $?判断是否执行成功,echo $?返回0代表执行成功,其他非0值代表执行失败;
  • -l :如果匹配成功只将文件名称打印出来,常与-r连用;
  • -A :如果匹配成功,则将匹配行及其后n行一起打印出来;
  • -B :如果匹配成功,则将匹配行及其前n行一起打印出来;
  • -C :如果匹配成功,则将匹配行及其前后n行一起打印出来;
  • --color:赋予颜色展示,默认携带参数;
  • -c :如果匹配成功,则将匹配的行数打印出来;
  • -E :等同于egrep
  • -i :忽略大小写;
  • -v :取反,即不匹配;
  • -w :完全匹配;
  • -r:递归匹配目录下文件内容。

1.2 使用方法

# 直接使用
[root@localhost shell]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# 显示行号
[root@localhost shell]# grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

# 静默输出判断
[root@localhost shell]# grep -q root /etc/passwd
[root@localhost shell]# echo $?
0

# 匹配成功返回文件名称,返回为文件绝对路径
[root@localhost shell]# grep -lr root /etc/passwd
/etc/passwd

# 匹配成功向下多打印2行
[root@localhost shell]# grep -n -A 2 root /etc/passwd
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
--
10:operator:x:11:0:operator:/root:/sbin/nologin
11-games:x:12:100:games:/usr/games:/sbin/nologin
12-ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

# 匹配忽略大小写
[root@localhost shell]# grep -i Root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# 完全存在bin的行反向匹配(内容过多,只显示一行)
[root@localhost shell]# grep -w -v bin /etc/passwd | head -n 1
daemon:x:2:2:daemon:/sbin:/sbin/nologin

# 递归匹配(首先显示当前执行目标目录的相对路径,其次回显匹配内容)
[root@localhost shell]# cp /etc/passwd .
[root@localhost shell]# cp /etc/shadow .
[root@localhost shell]# grep -r root .
./passwd:root:x:0:0:root:/root:/bin/bash
./passwd:operator:x:11:0:operator:/root:/sbin/nologin
./shadow:root:$1$Be4wm3PK$ewirp4uOSHUMaxelB2bRG.::0:99999:7:::
# 添加-n可以增加回显行号,推荐共用
[root@localhost shell]# grep -r -n root .
./passwd:1:root:x:0:0:root:/root:/bin/bash
./passwd:10:operator:x:11:0:operator:/root:/sbin/nologin
./shadow:1:root:$1$Be4wm3PK$ewirp4uOSHUMaxelB2bRG.::0:99999:7:::

# 扩展正则匹配
[root@localhost shell]# grep -Ew "^[a-z]{4}\:{0,1}" passwd 
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
sssd:x:979:977:User for sssd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
rngd:x:975:973:Random Number Generator Daemon:/var/lib/rngd:/sbin/nologin

2、Sed - 行匹配

流编辑器stream editorsed命令是将一系列的编辑命令应用与一批文本的理想工具,sed命令拥有非交互式和高效的特点,可以为用户节省大量的时间;sed命令是一个非交互式的文本编辑器,它可以对来自文本文件以及标准输入的文本进行编辑,其中标准输入可以是来自键盘、文件重定向、字符串、变量或者管道的文本;sed命令会从文件或者标准输入中一次读取一行数据,将其复制到缓冲区,然后读取命令行或者脚本的编辑子命令,对缓冲区中的文本进行编辑,重复此过程直到文本处理完毕。

2.1 执行原理

sed执行原理

模式空间pattern space

  • sed在内存里开辟模式空间,处理文件的每个输入行,最多8192字节;
  • PATT处理文件的内容,对输入行使用命令进行处理;

保存空间 holding space

  • sed在内存里开辟保留空间,保存已经处理过的输入行,最多8192字节;
  • HOLD默认有一个空行,保存已经处理过的输入行的空间,也在内存上;

命令执行原理

  • sed编辑器逐行处理文件,并将结果输出打印到屏幕上;
  • sed命令将当前处理的行读入模式空间进行处理;
  • sed处理完一行将其从模式空间中删除,然后将下一行读取模式空间进行处理、显示,直至处理完最后一行;
  • sed在临时缓冲区对文件进行处理,所以不会修改原文件,除非显示指明-i选项;
  • sed运行过程中维护这两个缓冲区,一个是活动的模式空间,另一个是起辅助作用的暂存缓冲区;

2.2 常见语法

sed OPTIONS... '[动作]' [文件名称...]
  • -n-quiet :不输出模式空间中的内容,不带n会回显文件原内容,查找到的行进行双重回显;

  • -i :直接编辑原文件,默认不对原文件进行操作

  • -e :使用多个命令进行操作

  • -f /path/from/sed_script :从指定的文本中读取处理脚本

  • -r :使用扩展正则表达式

2.3 使用方法

sed的常见使用方法与参数详解;

2.3.1 地址边界的设定

  • ##为数字,指需要操作处理的行

  • $ :表示最后一行,多个文件进行操作的时候,为最后一个文件的最后一行

  • /regexp/ :表示能够被regexp匹配到的行,基于正则表达式匹配

  • /regexp/I :不区分大小写

  • \%regexp%%为边界定位符,可以用其他符号替代

  • addr1,addr2 :指定范围内的所有行

  • first~step :指定起始位置与步长

  • addr1,+N :指定行以及以后的N行

  • addr1,~N :指定行以及以前的N行

操作案例

# 回显第3行
[root@localhost shell]# sed -n '3p' test.txt
# 回显第3行与第5行
[root@localhost shell]# sed -n '3p,5p' test.txt
# 回显第2至第5行
[root@localhost shell]# sed -n '2,5p' test.txt
# 回显第10行至末尾行
[root@localhost shell]# sed -n '10,$p' test.txt
# 回显数字重复3次的行
[root@localhost shell]# sed -n '/[0-9]{3}/p' test.txt
# 回显指定显示内容到另一个指定显示内容的行,aaa与bbb均需要存在,无开头无回显, 无结尾回显至末尾
[root@localhost shell]# sed -n '/aaa/,/bbb/p' test.txt

2.3.2 基础编辑命令

  • d :删除匹配到的行,d不能与参数-n并用
  • p :打印模式空间中的内容
  • a \textappend,在匹配到的行之后添加内容
  • i \text insert,在匹配到的行之前追加内容
  • c \textreplace,在匹配到的行和给定的内容进行文本替换
  • s /regexp/replacement/flags substitute 查找替换,把text替换为regexp匹配到的内容,/可以用其他无特殊任意符号代替

其他编辑命令:

    • r :读入文件内容追加到匹配行后面
    • R :读入文件一行内容追加到匹配行后面

常用flags

    • gglobal 全局替换
    • i :不区分大小写
    • pprint成功替换则打印输出
  • yy/source/dest/ 固定长度替换,要求替换长度相同

  • w /path/to/somefile:将匹配到的文件另外保存到指定文件中

操作案例

# 替换每行第一个north为hello
[root@localhost shell]# sed 's/north/hello/' test.txt
[root@localhost shell]# sed 'sAnorthAhelloA' test.txt
[root@localhost shell]# sed 's#north#hello#' test.txt
# 全部替换
[root@localhost shell]# sed 's/north/hello/g' test.txt
# 替换第一行所有的north
[root@localhost shell]# sed '1 s/north/hello/g' test.txt
# 替换第一行第一个north
[root@localhost shell]# sed '1 s/north/hello/' test.txt
# 替换第一行第二个north
[root@localhost shell]# sed '1 s/north/hello/ 2' test.txt

# 删除第3行并回显(文件内容并不会删除)
[root@localhost shell]# sed '3d' test.txt
# 删除第3行至第5行
[root@localhost shell]# sed '3,5d' test.txt
# 删除某个配置文件中的空行与注释
[root@localhost shell]# sed -r '/^$|^#/d' /etc/ssh/sshd_config 

# 在第3行前加入/后加入/替换第3行,命令中间空格可以自动识别,推荐加上
[root@localhost shell]# sed '3i ----------' test.txt
[root@localhost shell]# sed '3a ----------' test.txt
[root@localhost shell]# sed '3c ----------' test.txt

2.3.3 扩展操作

  • ! :对指定行以外的所有行应用命令
  • = :打印当前行号
  • ~ :表示从First开始,以步长Step递增
  • & :代表被替换的内容
  • : :命令并列
  • { } :对单个地址或地址范围进行批量操作
  • +:地址范围中用到的符号,加法运算符
  • ( ):对匹配内容进行排序并调用

操作案例

# -n 去掉默认输出,2,4p 输出第2行、第4行的内容,= 输出剩余全部行号
[root@localhost shell]# sed -n '3,4p;=' test.txt
# 3,4{p;=}输出第3行与第4行的内容与行号
[root@localhost shell]# sed -n '3,4{p;=}' test.txt
# 删除某个配置文件中的空行与注释
[root@localhost shell]# sed -nr '/^$|^#/!p' /etc/ssh/sshd_config 
# \1代表第一个()内容,\2代表第二个()内容
[root@localhost shell]# echo aaaaa_bbbbb | sed -r 's/(^.*)_(.*$)/\2_\1/g'
bbbbb_aaaaa

2.3.4 命令执行案例

  • 把/etc/passwd 复制到/tmp/test.txt,用sed打印所有行;
[root@localhost shell]# cp /etc/passwd ./test.txt sed -n 'p' test.txt
  • 打印test.txt的3到10行;
[root@localhost shell]# sed -n '3,10p' test.txt  
  • 打印test.txt 中包含’root’的行;
[root@localhost shell]# sed -n '/root/p' test.txt 
  • 删除test.txt 的15行以及以后所有行;
[root@localhost shell]# sed -n '15,$p' test.txt 
  • 删除test.txt中包含’bash’的行;
[root@localhost shell]# sed -n '/bash/d' test.txt 
  • 替换test.txt 中’root’为’toor’;
[root@localhost shell]# sed -n 's/root/toor/gp' test.txt 
  • 替换test.txt中’/sbin/nologin’为’/bin/login’
[root@localhost shell]# sed -n 's@/sbin/nologin@/bin/login@g' test.txt 
# 注意一点就是分隔符可以是任意不相同字符,并不仅仅是/ 
  • 删除test.txt中5到10行中所有的数字;
[root@localhost shell]# sed -n '5,10 s/[0-9]//gp' test.txt 
  • 删除test.txt 中所有特殊字符(除了数字以及大小写字母);
[root@localhost shell]# sed -n 's/[^a-zA-Z0-9]//gp' test.txt 
  • 在test.txt 20行到末行最前面加’aaa:’
[root@localhost shell]# sed -n '20 s/$/aaa:/p' test.txt 
  • 删除centos7系统/etc/grub2.cfg文件中所有以空白开头的行的行首空白字符
[root@localhost shell]# sed '/^ /d' /etc/grub2.cfg 
  • 删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符
[root@localhost shell]# sed '/^# /d' /etc/fstab

3、Awk - 列匹配

模式扫描和文本处理语言Pattern scanning and text processing languageawk适合于文本处理和报表生成,awk是一种非常强大的数据处理工具,其本身可以称为是一种程序设计语言,因而具有其他程序设计语言所共同拥有的一些特征,例如变量、函数、表达式等,通过awk用户可以编写一些非常实用的文本处理工具;

3.1 awk能做什么

awk是Linux以及Unix环境中现有的功能最强大的数据处理工具,简单来说,awk是一种处理文本数据的编程语言,awk的设计使得它非常适合于处理由行和列组成的文本数据,而在Linux或者Unix环境中,这种类型是非常普遍的;

awk还是一种编程语言环境,它提供了正则表达式的匹配,流程控制、运算符、表达式、变量以及函数等一系列的程序设计语言所具备的特性,它从C语言中获取了一些优秀的思想,awk程序可以读取文本文件,对数据进行排序,对其中的数值执行计算已经生成报表等;

3.2 执行原理

awk执行原理

awk来处理数据,在awk处理数据时,它会反复执行下面4个步骤:

  • 自动从指定的数据文件中读取行文本;
  • 自动更新awk的内置系统变量的值,例如列数变量NF、行数变量NR、行变量$0以及各个列变量$1$2等;
  • 依次执行程序中所有的匹配模式及操作;
  • 当执行完程序中所有的匹配模式及其操作之后,如果数据文件中仍然还有未读取的数据行,则返回到第一步,重复执行;

awk执行原理

3.3 命令的使用

命令执行

awk 'program-text' datafile

执行awk脚本

awk -f program-file file
# -f : 从脚本文件program-file中读取awk脚本,file为执行脚本目标文件

可执行的脚本文件

#!/bin/awk -f
awk-script file
# awk-script为awk脚本文件名称,file为执行脚本目标文件

3.4 语法格式与使用

awk [options] 'script' file1 file2 ...
# awk [选项] '脚本' 目标文件路径

awk [options] 'PATTERN {action}' file1 file2 ...
# awk [选项] '条件{动作}' 目标文件路径

3.4.1 输出方式

常见的输出类型主要有:print、变量输出、操作符、布尔值、模式结构、控制语句;

3.4.1.1 print的使用格式与参数
print item1,item2,...
  • 各项目之间使用逗号隔开,而输出时则以空白字符分隔;
  • 输出的item可以为字符串或数值、当前记录的字段、变量或awk表达式,数值会先转换为字符串,而后输出
  • print命令后面的item可以省略,此时其功能相当于print $0,若想输出空白行,需要使用 print " "
# print示范案例
[root@localhost shell]# awk 'BEGIN{ print "line one\nline two\nline three" }'
line one
line two
line three
[root@localhost shell]# awk -F: '{print $1,$2,$3}' test.txt
root x 0
bin x 1
daemon x 2

# 获取网卡IP地址
[root@localhost ~]# ifconfig br0 | awk 'NR==2{print $2}'
10.81.20.166
[root@localhost ~]# ifconfig br0 | grep 10.81.20.166 | tr -s " " | cut -d " " -f 3
10.81.20.166
3.4.1.2 printf的使用格式与参数
  • 其与print命令的不同是,printf需要指定format
  • format用于指定后面的每个item的输出格式;
  • printf语句不会自动打印换行符 \n

format格式的指示符如下:

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

常用修饰符:

  • N :显示宽度
  • - :左对齐
  • + :显示数值符号

操作案例

[root@localhost shell]# awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd | head -n 3
root            0
bin             1
daemon          2

[root@localhost shell]# awk -F: '{print $1"\t\t\t"$NF}' /etc/passwd | column -t
# column -t 根据输入行数进行制表

[root@localhost shell]# awk -F: 'BEGIN{print "name\tuid\tgid\tshell"}{print $1"\t"$3"\t"$4"\t"$7}' test.txt 
name	uid	gid	shell
root	0	0	/bin/bash
bin        1	1	/sbin/nologin
daemon	2	2	/sbin/nologin
adm	3	4	/sbin/nologin
lp	        4	7	/sbin/nologin
3.4.1.3 重定向操作
print items > output-file		# 重定向
print items >> output-file		# 追加重定向
print items | output-file

特殊文件描述符:

  • /dev/stdin:标准输入
  • /dev/stdout:标准输出
  • /dev/stderr:错误输出
  • /dev/fd/N:某特定文件描述符
[root@localhost shell]# awk -F: '{printf "%-15s %i\n",$1,$3 > "test1"}' /etc/passwd

3.4.2 变量操作

3.4.2.1 记录变量
  • FSfield separator:读取文本时,所使用字段分隔符;
  • OFSoutput field separator:输出分隔符;
  • OFS="x" :指定输出分隔符
awk -F[分隔符,默认为空格] 'BEGIN{判断条件前执行的命令}判断条件{执行命令}END{判断条件后执行的命令}' 文件路径
# awk -F : F指定输入分隔符,等于-v FS=:(-v FS与-vFS均可识别),默认支持扩展正则

操作案例

[root@localhost shell]# awk -F: '{print $1,$NF}' test.txt | column -t
root    /bin/bash
[root@localhost shell]# awk -vFS=: '{print $1,$NF}' test.txt
root /bin/bash

[root@localhost shell]# ifconfig br0 | awk 'NR==2{print $2}'
10.81.20.166
# “+”为扩展正则表达式,代表出现一次或多次
[root@localhost shell]# ifconfig br0 | awk -F"[ ]+" 'NR==2{print $3}'
10.81.20.166
# 由于未匹配到多个空格,因此IP地址的位置,参考第一个匹配内容是单个空格还是多个空格
[root@localhost shell]# ifconfig br0 | awk 'NR==2'
        inet 10.81.20.166  netmask 255.255.255.0  broadcast 10.81.20.255
[root@localhost shell]# awk -F: -vOFS=: '{print $1,$NF}' test.txt
root:/bin/bash
[root@localhost shell]# awk -F: 'BEGIN{OFS=":"}{print $1,$NF}' test.txt
root:/bin/bash
3.4.2.2 数据变量
  • NRawk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;
  • NF:当前记录的字段个数,默认以空格为间隔符,可以使用$NF代表最后一列;
  • FNR:用于记录正处理的行是当前这一文件中被总共处理的行数;awk处理多个文件,各自文件计数;
  • ENVIRON:当前shell环境变量及其值得关系数组;

操作案例

# 输出第2行有几列
[root@localhost shell]# awk -F: 'NR==2{print NF}' test.txt 
7
# 输出共有几行
[root@localhost shell]# awk '{print NR}' test.txt
1
2
# 输出第2行最后一列内容
[root@localhost shell]# awk -F: 'NR==2{print $NF}' test.txt
/sbin/nologin
3.4.2.3 自定义变量

awk允许用户自定义变量,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头,awk变量名称区分字符大小写;

# 在awk中给变量赋值使用赋值语句进行赋值
[root@localhost shell]# awk 'BEGIN{test="hello";print test}'
hello
# 在awk中使用赋值变量
[root@localhost shell]# awk -v test="hello" 'BEGIN {print test}'
hello
3.4.2.4 常见操作符号

操作符号与Linux系统基本完全一致,一致则不做重复赘述,不一致提供相关解释。

算术运算符

  • -x :负值
  • +x :转换为数值
  • x^y :次方
  • x**y :次方
  • x*y :乘法
  • x/y :除法
  • x+y :加法
  • x-y :减法
  • x%y :取余

字符串操作符

[root@localhost shell]# awk 'BEGIN {print "This","is","test","!"}'
This is test !

赋值操作符

  • = :如果符号为=号,使用/=/会有语法错误,因此使用/[=]/代替;
  • +=:其余同普通运算完全一致;
  • -=
  • *=
  • /=
  • %=
  • ^=
  • **=
  • ++
  • `–`

布尔值

awk中任何非0或非空字符串都为真,反之则为假;

比较操作符

  • <
  • <=
  • >
  • >=
  • ==
  • !=
  • ~ :匹配,在正则表达式中^与$分别代表行开头与结束,在awk中代表列开头与结束
  • !~:不匹配,注意点同上

逻辑关系符

  • && :与
  • || :或
  • ! :非

条件表达式

  • if
  • elif
  • else
  • fi
3.4.2.5 常见模式
awk 'program' input-file1 input-file2 ...
#其中program为“
#pattern { action }
#pattern { action }
#...
3.4.2.6 模式类型
  • Regexp:正则表达式,格式为/regular expression/
  • Expression:表达式,其值非0或非空白字符时满足条件,
  • Ranges:指定匹配范围,格式为 pat1,pat2
  • BEGIN/END:特殊模式,仅在awk命令执行前/后运行一次
  • Empty:匹配任意输入行
3.4.2.7 Action类型
  • Expressions

  • Control statements

  • Compound statements

  • Input statements

  • Output statements

  • /正则表达式/:使用通配符的扩展集

    +匹配其前的单个字符一次以上,是awk自有的元字符,不适用于grepsed等;

    ? 匹配其前的单个字符一次或0次,是awk自有的元字符,不适用于grepsed等;

  • 关系表达式:可以用下面的运算符表中的关系运算符进行操作,可以是字符串或数字的比较;

  • 模式匹配表达式:指定一个行的范围,该语法不能包括BEGINEND模式;

  • BEGIN:用户指定在第一条输入记录被处理之前所发生的动作,通常在此设定全局变量;

  • END:用户在最后一条输入记录被读取之后发生的动作;

操作案例

# 使用正则表达式匹配
[root@localhost shell]# awk -F: '/^r/ {print $1}' /etc/passwd
root
rtkit
rpc
radvd
rpcuser
rngd

# 使用BEGIN
[root@localhost shell]# awk -F: 'BEGIN {printf "%-15s %-3s %-15s\n","user","uid","shell"} $3==0,$7~"nologin" {printf "%-15s %-3s %-15s\n",$1,$3,$7}' /etc/passwd
user            uid shell
root            0   /bin/bash
bin             1   /sbin/nologin

# 使用END
[root@localhost shell]# awk -F: 'BEGIN {printf "%-15s %-3s %-15s\n","user","uid","shell"} $3==0,$7~"nologin" {printf "%-15s %-3s %-15s\n",$1,$3,$7} END {print "-----End file-----"}' /etc/passwd
user            uid shell
root            0   /bin/bash
bin             1   /sbin/nologin
-----End file-----
3.4.2.8 控制语句
  • if-else语句格式:
if (表达式) {语句1} else if (表达式) {语句2} else {语句3}

操作案例:

[root@localhost shell]# awk -F: '{if ($1=="root") printf "%-10s %-15s\n", $1, "Admin"; else printf "%-10s %-15s\n",$1, "Common User"}' /etc/passwd | head -n 3
root       Admin
bin        Common User
daemon     Common User
  • while语句格式:
while (表达式) {语句}

操作案例:

[root@localhost shell]# awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd
[root@localhost shell]# awk -F: '{i=1;while (i<=NF) {if (length($i)>=4) {print $i};i++}}' /etc/passwd
  • do-while语句格式:
do {语句} while (条件)

操作案例:

[root@localhost shell]# awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd | head -n 3
root
x
0
#计算1-100的和
[root@localhost shell]# awk 'BEGIN{do{sum+=i;i++;}while(i<=100)print "sum =",sum}'
sum = 5050
  • for语句格式:
for(变量;条件;表达式){语句}
for(变量 in 数组){语句}

操作案例:

[root@localhost shell]# awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
[root@localhost shell]# awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd
#将/etc/passwd文件内容中的最后一行内容进行统计并制表
 [root@localhost shell]# awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){print A,BASH[A]}}' /etc/passwd | column -t
/bin/sync       1
/bin/bash       2
/sbin/nologin   43
/sbin/halt      1
/sbin/shutdown  1
 [root@localhost shell]# awk 'BEGIN{a[0]="aaa";a[1]="bbb";a[2]=111;a[3]=222;for(i in a) print a[i]}'
  • case语句格式:
switch (expression) { case VALUE or /REGEXP/: statement1,statement2,... default: statement1, ...}
  • breakcontinue语句格式:

常用于循环或case语句中

  • next语句格式:
[root@localhost shell]# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd |head -n 3
bin 1
adm 3
sync 5
3.4.2.9 数组操作
  • 创建数组
array[index-expression]

index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。

要遍历数组中的每一个元素,需要使用如下的特殊结构:

for (i in array) print array[i]
# i在awk中值为数组array中的下标,若想获取下标所对应的值,选用array[i]即可
[root@localhost shell]# awk 'BEGIN{a[0]="aaa";a[1]="bbb";a[2]=111;a[3]=222;for(i in a) print a[i]}'
aaa
bbb
111
222

# 统计某个日志文件内固定时间段访问IP数量
[root@localhost shell]# awk -F"[ ]" '/22:21/,/22:26/{print $1}' access.log-20211020 | awk '{IP[$1]++}END{for (i in IP) print i,IP[i]}' | column -t
192.168.28.143  16

[root@localhost shell]# netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
LISTEN 10
ESTABLISHED 1
# 每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引
  • 删除数组
delete array[index]
3.4.2.10 内置函数
  • split(string, array [, fieldsep [, seps ] ])

将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列;

[root@localhost shell]# date +%T | awk '{split($0,a,":");print a[1],a[2],a[3]}'
  • length([string])

返回string字符串中字符的个数;

[root@localhost shell]# awk 'BEGIN{print length("uplooking")}'
9
  • substr(string, start [, length])

取string字符串中的子串,从start开始,取length个;start从1开始计数;

[root@localhost shell]# awk 'BEGIN{print substr("uplooking",u,2)}'
up
  • system(command)

执行系统command并将结果返回至awk命令

[root@localhost shell]# awk 'BEGIN{print system("whoami")}'
  • systime()

取系统当前时间

[root@localhost shell]# awk 'BEGIN{print systime()}'
  • tolower(s)

将s中的所有字母转为小写

[root@localhost shell]# awk 'BEGIN{print tolower("WWW.baidu.COM")}'
  • toupper(s)

将s中的所有字母转为大写

[root@localhost shell]# awk 'BEGIN{print toupper("WWW.baidu.COM")}'
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Shell ❀ 三剑客 - Grep + Sed + Awk 的相关文章

  • 如何将 bash 脚本的整个输出保存到文件

    我正在尝试将 bash 脚本的整个输出保存到文件中 我目前在代码开头有一个参数 ip 地址 如下所示 bin bash USAGE Usage 0
  • 在 Fish Shell 中设置导出

    我安装了多个版本的 PHP 对于我的正常开发 我总是使用通过自制程序安装的 PHP 5 5 x 在鱼壳里 which php php version gt usr local bin php gt PHP 5 5 8 cli built J
  • 如何在lua中获取shell脚本的返回码?

    我正在lua中执行一个脚本 os execute sh manager scripts update system sh f 我想获得脚本的输出 如果退出状态为 7 则返回 7 I tried local output os execute
  • bash 变量中的 Linux 鞭尾/对话框参数错误

    有人可以解释为什么下面的代码不起作用吗 我要疯狂地想找出答案 bin bash TEST M1 1 wire Interface ON echo TEST RESULT dialog title Config Modules State c
  • 如何使用 sed 仅删除双空行?

    我找到了这个问题和答案 https stackoverflow com questions 4651591 howto use sed to remove only triple empty lines关于如何删除三重空行 但是 我只需要对
  • ReferenceError:MongoDB shell 中未定义 require

    我尝试通过 Windows 命令 Windows 8 1 从 Mongo 客户端连接 MongoDB 当我使用require 在 javascript 中 我遇到如下错误 有人有同样的问题吗 我有错过任何一个吗require有关的npm安装
  • Bash 解析和 shell 扩展

    我对 bash 解析输入和执行扩展的方式感到困惑 对于输入来说 hello world 作为 bash 中的参数传递给显示其输入内容的脚本 我不太确定 Bash 如何解析它 Example var hello world displaywh
  • 通过特定分隔符删除字符串

    我的文件中有几列 其中第二列有 分隔符 我想删除第二列中的第一个 第三个和第四个字符串 并将第二个字符串留在该列中 但我有正常的分隔符空间 所以我不知道 input 22 16050075 A G 16050075 A G 22 16050
  • Grep 和 Python

    我需要一种通过 Unix 命令行中的正则表达式使用 grep 搜索文件的方法 例如 当我在命令行中输入 python pythonfile py RE file to be searched 我需要正则表达式 RE 在文件中搜索并打印出匹配
  • chown:不允许操作

    我有问题 我需要通过 php 脚本为系统中的不同用户设置文件所有者权限 所以我通过以下命令执行此操作 其中 1002 是系统的用户 ID file put contents filename content system chown 100
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • 有没有办法让我简化这些回声? [复制]

    这个问题在这里已经有答案了 我仍在学习如何编写 shell 脚本 并且我面临着一个挑战 让我更容易回显 Name1 Name2 Name15 我不太确定从哪里开始 我已经想法 但如果我搞砸了 我不想看起来很傻 有什么帮助吗 我实际上还没有尝
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t
  • awk/Unix 分组依据

    有这个文本文件 name age joe 42 jim 20 bob 15 mike 24 mike 15 mike 54 bob 21 试图得到这个 计数 joe 1 jim 1 bob 2 mike 3 Thanks awk F NR
  • 如何在 Linux shell 中将十六进制转换为 ASCII 字符?

    假设我有一个字符串5a 这是 ASCII 字母的十六进制表示Z 我需要找到一个 Linux shell 命令 它将接受一个十六进制字符串并输出该十六进制字符串代表的 ASCII 字符 所以如果我这样做 echo 5a command im
  • 如何查找所有以句号结尾的单词?

    我有一个包含许多以 a 结尾的单词的文件 其中大部分是缩写 例如 etc p s 如何输出一个仅显示一次所有这些单词的列表 所有单词前面都有一个空格 因此可以使用该空格来查找单词的开头 没有一个单词出现在该行的开头 文件中没有句子 因此句点
  • 从 shell 命令调用 SOAP 请求

    我使用curl 向Web 服务发送SOAP 请求 并使用shell 脚本获取响应 请在下面找到我正在使用的命令 curl H Content Type text xml charset utf 8 H SOAPAction d sample
  • 使用 sh 运行 bash 脚本

    我有 bash 脚本 它需要 bash 另一个人尝试运行它 sh script name sh 它失败了 因为 sh 是他的发行版中 dash 的符号链接 ls la bin sh lrwxrwxrwx 1 root root 4 Aug
  • 从 UNIX 命令行向串行端口发送字节?

    我想使用命令行将字节流发送到串行端口 这可能吗 我的串口位于 dev cu usbserial A700dYoR在我的 Mac 上 例如 如果我想将整数 50 或字符串 data 发送到该串行端口 我该怎么做 我对 UNIX 的了解非常有限
  • 分叉/多线程进程|重击

    我想让我的代码的一部分更加高效 我正在考虑让它分叉成多个进程 并让它们一次执行 50 100 次 而不是只执行一次 例如 伪 for line in file do foo foo2 foo3 done 我希望这个 for 循环运行多次 我

随机推荐

  • ubuntu20.4安装python3.8

    ubuntu20 4中安装python3 8 注 ubuntu20 4自带python3 10 软连接python3与pip3指向的为python3 10本文意在安装python3 8 并将软连接python与pip指向python3 8
  • C/C++多线程、线程同步(互斥锁与信号量)

    参考链接2 中写的非常好 xff0c 简单易懂 xff0c 上手快 xff0c 非常好的博文 使用多线程及互斥锁样例 xff1a include lt iostream gt include lt windows h gt using na
  • Python ❀ 初学者学习笔记与知识点梳理

    软件安装与环境部署变量与数据类型列表与元组条件判断语句字典while循环函数类文件与异常 推荐代码练习地址 xff1a https www runoob com python python 100 examples html 点击此处直接跳
  • Shell ❀ Linux系统自动挂载本地yum源并安装rpm依赖包

    文章目录 1 脚本代码详解2 代码执行结果3 脚本参数调整 1 脚本代码详解 span class token comment bin bash span span class token builtin class name echo s
  • Windows ❀ Windows系统下端口连通性常见的验证方法

    文章目录 1 telnet1 1 telnet服务开启方法1 2 端口连通性验证 2 tcping2 1 tcping下载与安装2 2 端口连通性验证 3 netstat ano findstr3 1 findstr使用语法3 2 端口连通
  • Security ❀ 安全设备学习规范(第二版)

    文章目录 安全设备学习规范1 设备部署环境1 1 部署方式1 2 配置IP地址与路由1 3 设备冗余机制1 4 会话同步机制1 5 设备账户管理1 6 设备故障诊断 2 产品授权方式2 1 序列号2 2 Hash值 3 相关设备联动3 1
  • Windows ❀ 解决Google浏览器无法访问网页问题

    文章目录 问题 xff1a Google浏览器无法访问网页解决方法 问题 xff1a Google浏览器无法访问网页 使用Google浏览器打开某个已知安全网页时 xff0c 弹出如下信息 xff0c 错误内容如下 xff1a NET ER
  • Security ❀ CSP Bypass 内容安全策略绕过

    文章目录 内容安全策略绕过 CSP Bypass1 Low Level2 Medium Level3 High Level4 Impossible Level 内容安全策略绕过 CSP Bypass CSP 内容安全策略 xff1a 为了缓
  • Security ❀ JavaScript Attacks 前端攻击

    文章目录 JavaScript Attacks 前端攻击1 Low Level2 Medium Level3 High Level4 Impossible Level JavaScript Attacks 前端攻击 JavaScript是一
  • MiddleWare ❀ Zookeeper基础概述

    文章目录 1 认识Zookeeper1 1 数据类型1 2 监听器1 3 基本功能1 3 1 统一配置管理1 3 2 统一命名服务1 3 3 分布式锁1 3 4 集群状态 2 下载安装包3 安装服务3 1 服务端命令3 2 客户端命令 3
  • Java文件内容变更及内容追加监听方案

    简介 对于文件内容变动的监听处理 xff0c 一般分为两种主要应用场景 1 只关心文件内容是否发生变更 文件的内容发生变动的场景是全量修改模式 xff0c 不是内容追加模式 例如某xml文件内容发生变动 这种情况 xff0c 我们一般只需要
  • MiddleWare ❀ MySQL基础概述

    文章目录 MySQL基础1 SQL语法与分类1 1 DDL 数据定义语言1 1 1 库操作1 1 1 1 查询1 1 1 2 创建1 1 1 3 删除1 1 1 4 使用 1 1 2 表 43 字段操作1 1 2 1 查询1 1 2 2 创
  • Shell ❀ 基础知识概述

    文章目录 一 基本概念1 脚本文件命名方式2 解释器分类3 基本基本组成内容4 脚本编写规范与格式说明5 自动生成脚本的注释与配置信息 一 基本概念 shell又称为命令解释器 xff0c 它能识别用户输入的各种命令 xff0c 并传递给操
  • Shell ❀ 基础变量类别与引用

    文章目录 二 变量与引用1 变量命名2 变量类型3 变量定义4 常用变量4 1 内置通配符4 2 内置变量4 3 自定义变量4 4 环境变量4 5 变量的作用域4 5 1 全局变量4 5 2 局部变量 4 6 位置变量4 5 1 位置变量的
  • Shell ❀ 条件测试语句

    文章目录 三 条件测试1 基本语法2 表达式2 1 条件判断表达式2 2 字符串判断表达式2 3 数字判断表达式2 4 文件判断表达式2 5 表达式中 与 的区别2 5 1 的逻辑判断表达式2 5 2 的逻辑判断表达式 三 条件测试 1 基
  • Shell ❀ 条件判断语句

    文章目录 四 条件判断1 if 单分支格式1 1 语法格式1 2 操作案例 2 if else 双分支格式2 1 语法格式2 2 操作案例 3 if elif else 多分支结构3 1 语法格式3 2 操作案例 4 和 复合指令4 1 相
  • Shell ❀ 循环语句

    文章目录 五 循环语句1 for 循环1 1 带列表的for循环1 2 不带列表的for循环1 3 类C风格的for循环 2 while 循环2 1 循环体读取文件的三种方法2 2 循环类型 3 嵌套循环案例 五 循环语句 1 for 循环
  • Shell ❀ 函数与数组

    文章目录 六 函数与数组1 函数1 1 函数定义1 2 函数的优势1 3 函数语法1 4 函数调用1 5 操作案例1 6 函数库文件1 7 递归函数 2 数组2 1 数组定义2 2 定义股关联数组2 3 数组的赋值2 4 数组操作2 5 数
  • Shell ❀ 正则表达式

    文章目录 七 正则表达式1 普通字符2 非打印字符3 特殊字符4 限定字符5 常用的正则表达式5 1 校验数字的表达式5 2 校验字符的表达式5 3 特殊需求表达式 七 正则表达式 正则表达式 Regular Expression xff1
  • Shell ❀ 三剑客 - Grep + Sed + Awk

    文章目录 八 三剑客 Grep 43 Sed 43 Awk1 Grep 过滤1 1 常用grep参数1 2 使用方法 2 Sed 行匹配2 1 执行原理2 2 常见语法2 3 使用方法2 3 1 地址边界的设定2 3 2 基础编辑命令2 3