awk:
awk的核心概念是“域”,所谓“域”就是把一行字符按照特定的分隔符分成一列列的内容。awk的操作就是逐行的对每一行的每一个域进行操作,以实现类似于二维表格的各种功能。
- 简单输出
对每一行都是以空格为分隔符的文件做输出选择。比如ls –l的结果,除去第一行后,仅仅想要得到权限情况和文件名。

可以看到,每一行被一个或者多个空格(或者制表符)分为9部分内容。每一部分内容就是一个域,awk中都有一个特定的标示符来表示一个域。awk中,默认的分隔符就是一个或者多个空格(或者制表符)。

语句的具体含义是:
- 花括号前没有任何的语句,说明是默认的对每一行进行操作,而没有任何的限制;
- 花括号中是打印语句,这里打印了1和1和1和NF。Awk顺序的为每一个域分配域号,$1代表从左边起第一个域,2代表第二个……。也可以从右向左数,2代表第二个……。也可以从右向左数,2代表第二个……。也可以从右向左数,NF代表最后一个,$NF-1代表倒数第二个;
- 打印语句中的“,”代表仍然使用默认的分隔符:一个空格,来分隔打印出来的内容。默认的分隔符分为输入和输出两种,输入可以使用“-F”参数来改变


实际上,shell本身不支持浮点运算,经常需要使用awk的浮点运算,例如:

第1条语句只是给awk一个空行,让其可以顺利执行。
2.指定分隔符
单字符分隔符:打印系统中用户名和其使用的shell类型

统计ngix日志中访问的IP以及访问的次数
先按GET分割获取第1个域,也就是来源IP所在的域;再按-分割只要IP地址;对IP排序;uniq统计出现的次数

多字符分隔符:
取得“GET”之后,“?”之前的内容

截取ip地址
使用grep

使用awk

正则分隔符获取IP地址:

以字母、冒号和空格的组合作为分隔符,可以很容易的数字和点组合的ip地址抽取出来。
注意:这里的[a-zA-Z ]*充分的利用了正则的贪婪性,正则会将方括号内的所有元素都尽量多的匹配在一起。
- 匹配打印
查看/etc/passwd中添加的用户列表:

和sed一样,awk的匹配模式也在/ /中,这行代码的意思是如果匹配“home”的行,就把该行的第一个域打印出来。可以看到,这个操作实际上代替了grep home|awk –F: ‘{print $1}’。
使用不匹配操作显示系统默认的用户:

判断打印:
找到非系统用户:

可以看到,匹配操作在{ }中,这是读取该行内容后的操作。在awk中,if语句后紧跟一对(),其中的语句主要是对域的各种判断,有匹配操作“~”、等于“==”、大于“>”、小于“<”、大于等于”>=”、小于等于“<=”,等。If语句后,紧跟print语句,可以打印满足条件的内容。
查看/etc目录中大小超过100K的目录列表

3. 数组的简单使用
awk的数组,一种关联数组(Associative Arrays),下标可以是数字和字符串。无需对数组名和元素提前声明,也无需指定元素个数。
awk脚本分为三段,命令行格式如下:
#awk ‘BEGIN{ }{ }END{ }’
之前未曾用到BEGIN和END。BEGIN中可以更改全局变量、打印一些表头内容;END中可以打印计算结果、统计等内容。中间的部分是awk逐行扫描计算的过程,之前学习的print、匹配后print等都是在这个部分完成打印,因为我们需要知道的就是中间逐行扫描过程中的结果。
数组计算通常是在中间部分进行,但是数组的打印一定是在END中。中间部分也可以进行数组的打印,但是打印结果随着不同行的扫描不停的变化,没有实际意义

awk ‘{a[$1]++}END{for (i in a){print a[i],i}}’
a[$1]++:声明一个数组,以$1也就是第一个域为下标,第1次为1,再出现这个值时就自增1。里面放什么就是什么,其实里面存的是键值对,类似于python的字典。
END:将算完的结果打印输出
for (i in a){print a[i],i}:遍历输出下标对应的值和下标
对域做运算

定义了一个数组a,以$2作为下标,sum[$2]初始值为0,每次加上$3对应的值作为$2下标对应的值
统计访问IP的出现次数并从小到大排序输出

shell script:
sh:
使用默认的shell执行脚本。linux支持多种shell,包括bash、csh、ksh、tcsh等。目前centos使用bash,使用sh执行某个脚本,相当于使用bash执行该脚本。

可以看到sh只是一个软连接,真正的还bash
- 基本用法:
l sh scriptname
相当于使用bash执行scriptname这个文件,如果这个文件中的内容符合shell脚本的规范,就会被正确执行。(即使这个文件没有执行权限,使用sh也可以执行该文件)
[root@test test]# sh
sh-4.2# exit
exit
[root@test test]# which sh
/usr/bin/sh
[root@test test]# bash
[root@test test]# mkdir script
[root@test test]# cd scrip
bash: cd: scrip: No such file or directory
[root@test test]# cd script
[root@test script]# vi test.sh
[root@test script]# cat test.sh
echo ‘hahahh’
[root@test script]# sh test.sh (直接使用sh命令执行脚本)
hahahh
[root@test script]# cat test.sh |sh(通过管道传递给sh执行脚本)
hahahh
l sh –x scriptname
仍然是执行scriptname文件,但是执行的详细过程会打印出来,包括变量的赋值、判断和循环的执行过程等,通常用于调试脚本。
[root@test script]# sh -x test.sh (打开调试功能)
- echo hahahh
hahahh
l sh还可以接受来自管道的内容。将输出内容当成命令重新执行。
比如:

批量替换文件名(sed/awk + sh):
sed + sh:
ls|sed ‘s/([a-zA-Z])\1*…*/mv \1.txt \1.jpg/g’|sh

awk+sh:
[root@test test]# ls
a.jpg b.jpg c.jpg
[root@test test]# ls|awk -F. ‘{print $1}’
a
b
c
[root@test test]# ls|awk -F. ‘{print “mv “$1”.jpg “$1”.txt”}’
mv a.jpg a.txt
mv b.jpg b.txt
mv c.jpg c.txt
[root@test test]# ls|awk -F. ‘{print “mv “$1”.jpg “$1”.txt”}’|sh
[root@test test]# ls
a.txt b.txt c.txt
[root@test test]# ls|awk -F. ‘{print “mv “$1”.jpg”,$1".txt"}’|sh
print中的出现了逗号(,)就会打印默认的分隔符空格,也可以用" "

ssh:
ssh是OpenSSH工具的客户端,可以使用ssh协议,远程登录到另外的一台有ssh server的unix服务器上,打开一个终端。命令格式为:
ssh username@xxx.xxx.xxx.xxx <-p port>
其中:
l username@可以指定登录到远程机器后使用哪个用户名登陆,为空的话默认为当前用户;
l -p port 省略的话为默认的22端口,如果对方服务器指定了特殊的ssh端口,需要输入指定的端口。
ssh username@xxx.xxx.xxx.xxx cmd可以将任意的命令发送到远程服务器执行,并返回结果。在shell script中会大量用到。
ssh ip地址:默认以当前用户名登录,过程中需要输入密码

ssh ip地址 命令:远程执行命令,登录后执行输入的命令返回结果后退出回到当前环境

scp:
scp是远程拷贝命令,使用的是ssh协议。scp命令和cp命令比较类似,不同的是scp的拷贝是远程机器和本机之间的传输。
格式:
l scp username@xxx.xxx.xxx.xxx:/path/to/file /path/on/localhost/ 将远程文件拷贝到本地
l scp /path/to/file username@xxx.xxx.xxx.xxx:/path/on/remote/ 将本地文件拷贝到远程
可以在scp后增加-r参数,以传递文件夹;
可以增加-P参数,修改登陆的端口;
[root@test ~]# scp /tmp/log.txt 192.168.1.8:/home/(本机拷到远程)
root@192.168.1.8’s password:
log.txt 100% 112 9.2KB/s 00:00
[root@test ~]# scp zz1@192.168.1.8:/home /tmp/(远程拷到本机)
crontab:定时任务
crontab可以自动执行命令或者脚本。每一个用户都有一个crontab文件,写在不同用户的crontab中的命令,相当于该用户执行命令。
crontab –l:查看当前用户的crontab
crontab –e:编辑当前用户的crontab,-e参数使用后,相当于使用vi打开了crontab文件,编辑后需要保存退出
crontab在centos6有bug,crontab -e 编辑的时候如果断网,有可能会导致crontab文件被清空,所有一般先要备份(crontab -l >> /tmp/crontab.bak)一个crontab文件再去修改。如果出现了,如何找回计划任务,解决方法如下:
/var/log/crontab保存了所有的执行记录
[root@test home]# cd /var/log
[root@test log]# ls
anaconda boot.log-20190211 dmesg grubby_prune_debug messages sa tallylog yum.log
audit btmp dmesg.old lastlog qemu-ga secure tuned
boot.log cron firewalld maillog rhsm spooler wtmp
Crontab的基本格式:
-
-
-
-
- cmd
-
-
-
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
pv:uv: 10:1
日活:uv/10 0.1-0.3
是否有秒杀,秒杀的接口做压测,时间段
echo:
echo命令用来打印一串字符,这串字符可以直接跟在echo命令后,也可以在引号中,或者在命令替换的反引号中

说明:
l 命令引号中的内容会当做命令来执行
l 打开了-e参数才能解释转义字符
l -e参数后面的内容要用引号引起来
单引号、双引号和命令引号:
单引号:在shell中有特殊作用,单引号中的东西所见即所得
双引号:保证有特殊含义的字符会输出特殊的含义,没有的话就原意输出;保持双引号中的格式
反引号`:命令引号,适用于支持管道的命令,比如kill
[root@test test]# echo $PATH
/usr/local/apache-maven-3.6.1/bin:/usr/local/java/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@test test]# echo ‘$PATH’(单引号 所见即所得)
$PATH
[root@test test]# echo "PATH"(双引号输出PATH"(双引号输出PATH"(双引号输出PATH的真正含义)
/usr/local/apache-maven-3.6.1/bin:/usr/local/java/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@test test]#
一串字符串不加引号,shell会把换行、制表符、多个空格全部当成一个空格。比如:
[root@test test]# echo aa nn
aa nn
[root@test test]# echo ‘aa nn’
aa nn
[root@test test]# echo “aa nn”
aa nn
kill掉bash进程:
方式一:sh
[root@test test]# ps -ef|grep bash|grep -v grep|awk ‘{print $2}’
3296
22397
[root@test test]# ps -ef|grep bash|grep -v grep|awk ‘{print "kill "$2}’
kill 3296
kill 22397
[root@test test]# ps -ef|grep bash|grep -v grep|awk ‘{print "kill "$2}’|sh
方式二:
[root@test script]# ps -ef|grep bash|grep -v grep|awk ‘{print $2}’
3296
22397
[root@test script]# kill ps -ef|grep bash|grep -v grep|awk '{print $2}'(杀掉进程)
本文介绍了awk的核心概念——域,展示了如何使用awk处理ls输出,进行浮点运算,以及数组和正则表达式的应用。涵盖了基本语法、命令行使用、shell配合awk的实例和常见场景如文件替换、IP计数等。
2577

被折叠的 条评论
为什么被折叠?



