1、shell基本语法1.1、什么是shell命令解释器,和计算机对话的翻译官 1.2、什么是shell脚本提前编好的命令放在一个文件里面,一键直接执行 脚本命令都是单独一行,从上往下依次执行,第一行需要添加命令解释器#!/bin/bashdate命令:格式:date +%*%H : 小时(00-23) %M : 分钟(00-59)%S : 秒(00-60)%X : 相当于 %H:%M:%S%Z : 显示时区%d : 日 (01-31)%m : 月份 (01-12)%y : 年份的最后两位数字 (00.99)%Y : 完整年份 (0000-9999)%D : 直接显示日期 (mm/dd/yy)%F:显示日期,等同于%Y-%m-%d 1.3命令解释器1.3.1shell脚本的格式 1.3.2脚本的执行方式命令执行:bash sh source路径执行:/root/test.sh ./输入路径即可1.3.3传教shell脚本的步骤1、写脚本(包含基本的命令和控制语句等)2、检测语法错误3、添加执行权限4、执行1.4、管道与重定向管道操作若要提取根分区(/)的磁盘使用率信息,可以执行以下操作,其中用到了df、grep、awk命令和管道操作。 重定向操作标准输入:键盘输入,编号0标准输出:默认设备显示器。编号1标准错误:默认设备显示器,编号2linux系统中改变默认的输出输入,不用默认输出,这种操作是重定向重定向输入: 直接从pass.txt文件中提取创建用户使用的密码,省去了交互式的操作。重定向输出: uname信息是默认直接显示的,如果用了重定向输出直接出现在kerne1.txt文件中错误重定向 使用“2>”操作符时,会像使用“>”操作符一样覆盖目标文件的内容,若要追加内容而不是覆盖文件,应改为用“2>>”操作符。 在脚本中,使用&>/dev/null可以将标准输出和标准错误输出到同一个文件中也可以使用"exec >log.txt 2>&1" 命令。2、shell变量及运用2.1、变量的解释可以当做是一种容器,存储数据使用2.1.2 变量的设置与规则1.可以任意组合组合字符,但是不能以数字开头2.用=做分值3.存储的数据是整数和字符串值4.在对变量赋予字符串值时,建议大家用引号将其括起来,需要使用单引号或双引号5.调用时候前面要加
6.
如
果
需
要
增
加
变
量
的
值
,
那
么
可
以
进
行
变
量
值
的
叠
加
。
不
过
变
量
需
要
用
双
引
号
包
含
“
6.如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含“
6.如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含“变量名”或用
变
量
名
包
含
。
例
如
:
2.1.3
、
b
a
s
h
s
h
e
l
l
的
扩
展
功
能
我
们
最
常
见
的
就
是
扩
展
变
量
值
和
命
令
替
换
和
算
术
扩
展
{变量名}包含。例如: 2.1.3、bash shell的扩展功能我们最常见的就是扩展变量值和命令替换和算术扩展
变量名包含。例如: 2.1.3、bashshell的扩展功能我们最常见的就是扩展变量值和命令替换和算术扩展name是${name}的简化版,平时使用为了严谨避免出错,使用花括号name=“tom” 定义一个变量name,并将Tom字符串赋值给变量nameecho
n
a
m
e
L
i
如
果
不
使
用
花
括
号
引
起
变
量
名
会
变
量
n
a
m
e
和
L
i
混
淆
在
一
起
产
生
歧
义
。
命
令
替
换
:
将
执
行
的
命
令
替
换
成
变
量
值
语
法
:
a
=
{name}Li 如果不使用花括号引起变量名会变量name和Li混淆在一起产生歧义。命令替换:将执行的命令替换成变量值语法:a=
nameLi 如果不使用花括号引起变量名会变量name和Li混淆在一起产生歧义。命令替换:将执行的命令替换成变量值语法:a={命令} echo
a
若
要
提
取
根
分
区
(
/
)
的
磁
盘
使
用
率
信
息
并
赋
值
变
量
算
数
扩
展
使
用
a若要提取根分区(/)的磁盘使用率信息并赋值变量 算数扩展使用
a若要提取根分区(/)的磁盘使用率信息并赋值变量 算数扩展使用[]或
(
(
)
)
进
行
语
法
:
(())进行语法:
(())进行语法:((算术表达式))或
[
算
数
表
达
式
]
变
量
作
为
运
算
数
求
余
运
算
变
量
的
分
类
1
、
用
户
自
定
义
变
量
2
、
环
境
变
量
:
这
种
变
量
中
主
要
保
存
的
是
和
系
统
操
作
环
境
相
关
的
数
据
,
例
如
P
A
T
H
环
境
变
量
。
3
、
位
置
参
数
变
量
:
这
种
变
量
主
要
是
用
来
向
脚
本
当
中
传
递
参
数
或
数
据
的
,
变
量
名
不
能
自
定
义
,
变
量
作
用
是
固
定
的
。
4
、
预
定
义
变
量
:
是
B
a
s
h
中
已
经
定
义
好
的
变
量
,
变
量
名
不
能
自
定
义
,
变
量
作
用
也
是
固
定
的
。
2.2
用
户
定
义
变
量
对
变
量
赋
值
如
果
字
符
串
内
容
存
在
空
格
的
话
,
用
引
号
把
它
引
起
来
变
量
值
叠
加
使
用
[算数表达式]变量作为运算数 求余运算 变量的分类1、用户自定义变量 2、环境变量:这种变量中主要保存的是和系统操作环境相关的数据,例如PATH环境变量。 3、位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。 4、预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。2.2用户定义变量对变量赋值如果字符串内容存在空格的话,用引号把它引起来 变量值叠加使用
[算数表达式]变量作为运算数 求余运算 变量的分类1、用户自定义变量2、环境变量:这种变量中主要保存的是和系统操作环境相关的数据,例如PATH环境变量。3、位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。4、预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。2.2用户定义变量对变量赋值如果字符串内容存在空格的话,用引号把它引起来 变量值叠加使用{} 变量替换命令使用$()或者反引号`` 单引号和双引号区别单引内的单词没有特殊意义,双引号之间内容有特殊符号会保留特殊含义2.3环境变量全局变量和局部变量查看全局变量:env 或 printenv通过shell环境中通过bash可以进入子shell环境export 通过此命令可以实现全局变量source /etc/profile 实现永久全局变量2.4变量删除unset 变量名 不需要加 $2.5设置PATH环境变量PATH变量是用来定义命令和程序搜索路径的环境变量USER表示当前登录系统的用户名称环境变量HOME表示用户的宿主目录环境变量LANG表示语言和字符集环境变量PWD表示当前所在的工作目录。2.6位置变量 红框内的是位置变量,通过$0-
9
进
行
依
次
引
用
9进行依次引用
9进行依次引用 *表示所有位置参数的内容,即以一个字符串显示所有向脚本传递的参数;$*以"$1 $2 …
n
"
的
形
式
输
出
所
有
参
数
(
整
个
字
符
串
)
n"的形式输出所有参数(整个字符串)
n"的形式输出所有参数(整个字符串)#表示命令行中位置参数的个数,传递到脚本的参数个数
@
与
@与
@与*相同$@以"$1" “
2
"
…
"
2" … "
2"…"n” 的形式输出所有参数 (多数的单个字符串)$
当
前
进
程
的
进
程
号
P
I
D
当前进程的进程号PID
当前进程的进程号PID?显示上一条命令的退出状态;0表示没有错误,其他任何值表明有错误
!
后
台
运
行
的
最
后
一
个
进
程
的
进
程
号
p
i
d
3
、
数
学
运
算
方
法
:
1.
e
x
p
r
数
字
的
基
本
运
算
2.
使
用
双
括
号
(
(
)
)
格
式
:
!后台运行的最后一个进程的进程号pid3、数学运算方法:1.expr数字的基本运算2.使用双括号(()) 格式:
!后台运行的最后一个进程的进程号pid3、数学运算方法:1.expr数字的基本运算2.使用双括号(()) 格式:((表达式1,表达式2)) 1、在双括号结构中,所有表达式可以像c语言一样,如:a++,b–等。a++ 等价于 a=a+1 2、在双括号结构中,所有变量可以不加入:“
”
符
号
前
缀
。
(
当
然
变
量
名
前
也
可
以
”符号前缀。(当然变量名前也可以
”符号前缀。(当然变量名前也可以) 3、双括号可以进行逻辑运算,四则运算 4、双括号结构 扩展了for,while,if条件测试运算 做数字大小比较时,输出结果假为0,1为真;特殊符号用转义符 乘法运算中,*不能作为乘,会直接转成通配符使用,需要加\进行转义对字符串处理 运算符 意义++ --递增及递减,可前置也可以后置。如a++、++a+ - * / %加减乘除与余数< <= > >=比较大小符号== !=相等 不相等&& || !逻辑与 ,逻辑或,逻辑否? :条件判断= += -= *= /= %= 赋值运算符,a+=1相当于a=a+1递归递减a++先读取a的值,然后在累加1++a先累加1,然后再读取a的值条件判断条件判断的格式:条件?值1:值2 表示条件成立返回值1,否则返回值2例如:[root@localhost ~]# z=$((3>6?1:4))[root@localhost ~]# echo KaTeX parse error: Expected 'EOF', got '&' at position 216: …要用空格2.test测试命令 &̲&后面第一个为真,第二个为假整…a” == “
b
”
]
!
=
判
断
两
个
字
符
串
是
否
不
相
等
[
“
b” ]!=判断两个字符串是否不相等[ “
b”]!=判断两个字符串是否不相等[ “a” != “
b
”
]
−
z
字
符
串
判
断
字
符
串
是
否
为
空
[
−
z
“
b” ]-z 字符串判断字符串是否为空[ -z “
b”]−z字符串判断字符串是否为空[−z “a” ]-n 字符串判断字符串是否不为空[ -n “$a” ]str1 > str2判断字符串str1是否大于str2[ “str1” > “str2” ]str1 < str2判断字符串str1是否小于str2[ “str1” < “str2” ] 注意:对于进行字符串的测试,一定要将字符串加上双引号然后再进行比较,一定要注意空格,一般用在[ ]里面 逻辑操作符 注:[[ ]]是扩展test命令,&& 、|| 、> 、<像这样符号可以用在[[ ]]中,不能用在[ ]中。3流程控制语句if语句单分支 语法if [ 条件判断 ] ; then commandsfi注:条件判断用test进行判断 双分支 语法if [ 条件判断 ]then commandselse commandsfi条件判断用test进行判断多分支 If [ 条件判断1 ] ; then commandselif [ 条件判断2 ] ; then commandselif [ 条件判断3 ] ; then commands …else commandsFi 结构化命令case和for、while循环case格式适用于多分支,是一个多选择语句 case 变量值 in 模式1) 命令序列1 ;; 模式2) 命令序列2 ;; …… *) ;; 默认命令序列 esac多分支 case 条件语句只能判断变量中的值到底是什么,而不能像多分支if语句那样,可以判断多个条件,所以多分支 case 语句更加适合单条件多分支的情况。比如,我们在系统中经常看到请选择"yes/no",或在命令的输出中选择是执行第一个选项,还是执行第二个选项(fdisk 命令)。在这些情况下,使用 case 最为适合。我们写一个选择"yes/no"的例子,命令如下: 用户输入0-9任意一个数字,通过case来判断用户输入的是哪一个数字?[root@localhost ~]# cat case-1.sh #!/bin/bashread -p “Type a num > " NUMcase $NUM in 1) echo "Input a num is 1 " ;; 2) echo "Input a num is 2 " ;; [3-8]) echo “Input a num is $NUM” ;; 9|0) echo "Input a num is KaTeX parse error: Undefined control sequence: \0 at position 116: …中色彩的处理echo -e "\̲0̲33[31m 红色字 \033…IFSIFS=KaTeX parse error: Undefined control sequence: \n at position 2: ’\̲n̲’ …’\n’表示换行符for i in cat /etc/hosts
do echo
i
d
o
n
e
I
F
S
=
idoneIFS=
idoneIFS=OLD_IFS 数字列表的获取方式seq-w补全shell中使用for i in seq 2 8
do echo $idone while重复判断条件测试操作,只要条件成立就反复执行对应的命令序列(循环体),直到条件测试不成立或为假语法while 条件测试操作do命令序列done 范例2:编写脚本用于批量添加用户,要求如下: 要求提供交互功能,当管理员执行该脚本时,可以根据提示指定需添加的用户数量(少于100)、用户名前缀、并能够设置这些用户账户的失效时间,初始密码。用户名编号统一使用两位数,如使用”01”、”02”、”03”的形式,而不是”1”、”2”、”3”的形式。批量删除用户脚本myudel.sh内容如下: 猜价格游戏 第四章 shift位置参数左移、函数、退出循环 shift位置参数左移、函数、退出循环shift位置参数左移指令作用:执行一次,位置参数向左移动一次 实例:加法计算器[root@localhost ~]# cat shift.sh#!/bin/bashif [ $# -le 0 ];then echo “没有提供足够的参数” exit 1fisum=0while [ KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ -gt 0 ];do sum…[$sum+$1] shift done echo “result is $sum” 奇偶问题的代码#!/bin/bashsums=0while [ KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ -gt 0 ] do s…(($sums+$1)) shift 2 if [ KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ -eq 1 ] then …(($sums+$1)) break fi done echo “the sum is $sums” 2函数的使用定义:类似于变量,可以将脚本的中的比较长的脚本,定义成一个函数,用的时候直接用这个函数名就可以2.1创建函数#!/bin/bash# using a function in a script function func1() { #定义函数 echo “This is an example of a function”} count=1while [ KaTeX parse error: Expected 'EOF', got '#' at position 44: … #̲调用函数count=[ $count + 1 ]done echo "This is the end of the while"func1 #调用函数echo “Now this is the end of the script” 函数的返回值:函数默认退出的状态是最好一条命令的退出状态,如果返回值后面加上return 5 就可以定义退出的状态2.2向函数传递参数传递位置参数,#!/bin/bashfunction addem() { if [ $# -eq 0 ] || [ $# -gt 2 ] #定义函数 then echo “error,need to input one or two number.” elif [ $# -eq 1 ] then echo $[ $1 + $1 ] else #定义位置参数 echo $[ $1 + $2 ] fi}echo -n "Adding 10 and 15: "value=addem 10 15
#给函数的位置参数加上数字进行计算echo $value 函数中无法从脚本命令行中直接访问参数值,要使用函数中的值,必须手动传递数据#!/bin/bash# trying to access script parameters inside a function function func6 { echo $[ $1 * $2 ]} if [ $# -eq 2 ]then value=func6 $1 $2
#调用使用 echo "The result is $value"else echo "Usage: badtest1 a b"fi 3跳出循环break结束并跳出循环,进行后面的代码continue 跳过循环的值,继续进行下一个循环,中间空一个数值实例#!/bin/bashwhile truedo read -p “Enter a number [1-5]:” num case $num in 1|2|3|4|5) echo “GREATER” ;; *) echo “wrong…Bye” break #这里直接跳出来 esacdone continue实例root@localhost ~]# cat continue.sh #!/bin/bashwhile truedo echo -n “Input a number between 1 to 5: " read aNum case $aNum in 1|2|3|4|5) echo “Your number is KaTeX parse error: Expected 'EOF', got '#' at position 103: … continue #̲这里跳出来,进入下一个命令 …pre user password:
p
a
s
s
u
s
e
r
n
u
m
b
e
r
:
pass user number:
pass usernumber: num " read -p “Are you sure?[y/n] " action if [ “$action” == “y” ];then break #这里跳出while循环,进入创建用的for循环中 fidone#adduserfor i in $(seq -w
n
u
m
)
d
o
u
s
e
r
=
num)do user=
num)do user={pre}${i} id $user &> /dev/null if [ $? -ne 0 ];then useradd
u
s
e
r
e
c
h
o
"
user echo "
user echo"pass”|passwd --stdin $user &> /dev/null if [ KaTeX parse error: Undefined control sequence: \e at position 27: …hen echo -e "\̲e̲[31muser\e[0m create” fi else echo “User KaTeX parse error: Undefined control sequence: \n at position 239: …a。.匹配除换行符和回车符(“\̲n̲”和"\r")外的任意一个字符…匹配行尾。例如,helloKaTeX parse error: Expected group after '^' at position 17: …会匹配以 hello 结尾的行^̲匹配空行[]匹配中括号中指定的任意一个字符,而且只匹配一个字符。例如[aoeiu]匹配任意一个元音字母, [0-9] 匹配任意一位数字,[a-z][0-9] 匹配由小写字母和一位数字构成的两位字符,[a-zA-Z] 匹配任意一位英文字母 []匹配除中括号中的字符以外的任意一个字符。例如,[0-9] 匹配任意一位非数字字符,[^a-z] 匹配任意一位非小写字母,注意:可以用^标记做[]内的前缀,表示除[]内的字符以外的任意一个字符。比如:搜索oo前没有g的字符串的行,应用 ‘[^g]oo’ 作搜索字符串。符号如果出现在[]的起始位置表示否定,但是在[]的其他位置是普通字符。[ab^c] 匹配除了a、b、、c以外的任意单个字符。\转义符,用于取消特殊符号的含义,使该特殊字符成为普通字符。例如:.[0-9][0-9]表示匹配以一个句点和两个数字开始。{n}表示其前面的字符出现 n 次。例如,[0-9]{4} 匹配4位数字,1[35-9][0-9]{9} 匹配手机号码。{n,}表示其前面的字符出现不少于 n 次。例如,[0-9]{2,} 匹配两位及以上的数字{n,m}表示其前面的字符至少出现 n 次,最多出现 m 次。例如,[a-z]{6,8} 匹配 6〜8 位的小写字母<>匹配词(word)的开始(<)和结束(>)。例如正则表达式<the>能够匹配字符串"for the wise"中的"the”,但是不能匹配字符串"otherwise"中的"the”。注意:这个元字符不是所有的软件都支持的。 扩展字元符使用的时候要加egrep和不能使用grep,grep -E是同意思扩展元字符描述+匹配前面的一个字符或子表达式1次或任意多次。
如“go+gle”会匹配“gogle” “google”或“gooogle”。当然,如果“o”有更多个,则也能匹配。egrep “go+gle” filename或grep -E “go+gel” filename ?匹配前面的一个字符或子表达式零次或一次。例如:如 “colou?r” 可以匹配 “colour” 或 “color”|表示或。如“was|his”既会匹配包含“was”的行,或匹配包含“his”的行()将括号里的内容看成是一个整体。可以理解为由多个单个字符组成的大字符。
如“(dog)+”会匹配“dog” “dogdog” “dogdogdog”等,因为被()包含的字符会被当成一个整体。但 “hello(world|earth)” 会匹配 “hello world” 及 “hello earth” 显示sshd_config文件中有效的配置项[root@localhost ~]# egrep -v “#|KaTeX parse error: Expected 'EOF', got '#' at position 43: …ot@localhost ~]#̲ grep -E -v …” /etc/ssh/sshd_config、 利用正则表达式过滤出ip地址答案有很多种,提示:提示 :IP地址从0-255之间,要把0-255拆分成0-99,100-199,200-249,250-255,然后在分别过滤出4段就出来了。正则表达式书写如下所示:egrep ‘<(25[0-5]|[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})(.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})){3}>’ 路径 检索手机号grep 1[35-9][0-9]{9} 路径 匹配手机号码。 2、sed命令2.1概念sed全名叫stream editor,流编辑器。用无交互式的方式来编辑文本,sed处理数据前,需要先指定规则编辑数据,实现无交互的编辑数据,同时因为支持正则表达式作为参数。2.2处理过程1.将正在运行的数据保存到临时缓冲去(内存)2.在缓冲去进行处理,然后输出3.输出完毕将缓冲删除,进行下一次的命令。2.3使用格式[root@localhost ~]# sed [选项] ‘[动作指令]’ filename选项-n 默认情况下,sed 会在动作指令执行完毕后,自动输出处理后的内容,而该选项会屏蔽默认输出。-e 执行多个sed指令-i 此选项会直接修改源文件,要慎用,修改前建议先备份源文件。-i.bak 编辑源文件的同时创造.bak的备份-r 使用扩展的正则表达式 动作指令:p 打印 ,输出指定的行S 替换,替换指定字符串d 删除,删除行a 增加行,在当前行下面插入文件i 增加行,在当前行上面插入文件c 把选定的行改为新的指定的文本r 读取文件,即用于将一个独立文件的数据插入到当前数据流的指定位置w 另存为 命令的使用p是查看的意思默认输出所有行,日常使用加入准确数字提供多少行。 图上2p是查看第二行,4,6p查看46 行,需要配合-n使用s替换格式:sed ‘s/要被替换的字串/新的字串/g’例如:[root@localhost ~]# sed ‘s/hello/never/g’ test1.txt s "替换"命令
/…/…/ 分割符 (Delimiter)
hello 搜索字符串(要被替换的字符串)
never 替换字符串(新的字符串)[root@localhost ~]# sed ‘s/hello/never/2’ test1.txt //只替换每行出现的第二个词[root@localhost ~]# sed ‘s/hello/never/g’ test1.txt //全局替换按行查找替换[root@localhost ~]# sed ‘2s/never/dog/’ test2.txt 进行替换第二行,以此类推,输入数字确定行数多行替换[root@localhost ~]# sed ‘3,KaTeX parse error: Expected 'EOF', got '#' at position 79: …ot@localhost ~]#̲ sed 's/never/@…c\hello world’ test1.txtit is hello too old to learnhello world此命令和s替换相似,不同的是替换的是整个行数,上述命令是替换第二行和最后一行,整体替换成hello world’对文件的保存和读取r是格式:sed ‘r/文件名’ 当前指定文件名将整个独立的文件数据插入到当掐你文件的指定位置 使用时候,r前面加入数字是指行数,图上是将/etc/hosts文件内容插入test1.txt的文件中,可以配合KaTeX parse error: Expected 'EOF', got '#' at position 78: …ot@localhost ~]#̲ sed -i 's/cat/…/ {print “Blank line”}’ test.txt在此命令中,/^$/ 是一个正则表达式,功能是匹配文本中的空白行,同时可以看到,执行命令使用的是 print 命令,此命令经常会使用,它的作用很简单,就是将指定的内容进行输出。因此,整个命令的功能是,如果 test.txt 有 N 个空白行,那么执行此命令会输出 N 个 Blank line。匹配规则和执行条件条件类型条 件说 明awk保留字BEGIN在awk程序一开始,尚未读取任何数据之前执行。BEGIN 后的动作只在程序开始时执行一次awk保留字END在awk程序处理完所有数据,即将结束时执行。END 后的动作只在程序结束时执行一次关系运算符>大于<小于>=大于等于<=小于等于等于。用于判断两个值是否相等。如果是给变童赋值,则使用”=”!=不等于匹配表达式~(匹配)value ~ /regexp/ 如果value匹配/regexp/,则返回真!~(不匹配)value !~ /regexp/ 如果value不匹配/regexp/,则返回真正则表达式/正则表达式/如果在“//”中可以写入字符,则也可以支持正则表达式,如:/root/表示匹配含有root的行。逻辑运算符&&逻辑与||逻辑或 例如:
[root@localhost ~]# awk -F: ‘
7
/
b
a
s
h
7 ~ /bash
7 /bash/ {print $1}’ /etc/passwd判断
7
(
第
7
个
数
据
字
段
)
的
值
是
否
匹
配
正
则
表
达
式
/
b
a
s
h
7(第7个数据字段)的值是否匹配正则表达式/bash
7(第7个数据字段)的值是否匹配正则表达式/bash/[root@localhost ~]# awk -F: ‘
7
!
/
b
a
s
h
7 !~ /bash
7! /bash/ {print $1}’ /etc/passwd判断
7
(
第
7
个
数
据
字
段
)
的
值
是
否
不
匹
配
正
则
表
达
式
/
b
a
s
h
7(第7个数据字段)的值是否不匹配正则表达式/bash
7(第7个数据字段)的值是否不匹配正则表达式/bash/awk使用字段变量$0 代表整个文本行$1 代表数据的第一段
2
代
表
数
据
的
第
二
段
2 代表数据的第二段
2代表数据的第二段n 代表数据的第n段执行命令awk的执行命令在大括号{ }内指明。动作大多数用来打印(即print指令)但是还有些更长的代码诸如i f和循环语句及循环退出结构。如果不指明采取动作,awk将打印出所有浏览出来的记录。动作(Action):n 格式化输出(print);n 流程控制语句(if、while、for等);例如:显示passwd文件中第1个第6个字、段的信息 awk中的BEGIN和ENDBEGIN是在命令执行之前先执行一次,awk读取文件数据时候,先执行BEGIN再执行awk的命令。通常被用为设定数据标题使用 分析:-F先指定:为分隔符。BEGIN先执行设定“”“print username and loginshell”为标题$3(uid)位置的数据大于等于500时候打印出$1(用户名) $7(登录shell)的数据, END命令和BEGIN命令是相似的,不同的是在命令执行结束进行设定标题 分析:-F先指定:为分隔符。BEGIN先执行设定“”“print username and loginshell”为标题$3(uid)位置的数据大于等于500时候打印出$1(用户名) $7(登录shell)的数据,紧跟着在输出结果的末端打印出the end的末尾标题 awk工作过程 通过图片可以看出,awk是先执行BEGIN紧接着执行awk命令,END进行结束 1.如果BEGIN块存在,awk执行它指定的actions。2.awk从输入文件中读取一行,称为一条输入记录。(如果输入文件省略,将从标准输入读取),awk将读入的记录分割成多个字段,将第1个字段放入变量$1中,第2个字段放入$2,以此类推。$0表示整条记录。 3、把当前输入记录与awk中’匹配规则{执行命令}‘中的“匹配规则”比较,看是否匹配,如果相匹配,就执行对应的‘执行命令’。如果不匹配,就跳过对应的执行命令。 4、awk读取输入的下一行,继续重复步骤2和3,这个过程一直持续,直到awk读取到文件尾。 5、当awk读完所有的输入行后,如果存在END,就执行相应的actions。例如:显示最近登录系统的用户,要求只显示用户名和登录源使用awk命令抽取用户名和IP区域的数据 分析:先执行last查看出最近用户名登录的信息,通过管道符传输数据,执行BEGIN打印出标题,再次执行打印命令,打印出$1和 $2位置的参数 (”\t”是tab键的意思,可以用空格代替)awk的变量自定义变量:用户自己定义的变量,有两种形式-v var=value 赋值一个用户定义变量,将外部变量传递给awk 例如:统计用户数量: 分析:执行awk命令-v给var和count加入变量,先打印出var 的变量,紧接着执行count++的命令,因为awk是按照行数执行,所以每执行一次进行+1,最后打印出count最后的数量在program中直接定义,以下定义了3个自定义变量,其实形式像编程语言一样,定义的时候用分号。打印变量跟之前一样,用逗号隔开,注意,不需要用美元符号。awk 分析:先执行BEGIN的命令,在{}里面设定变量,每个变量需要用;隔出,最后将三个变量打印出来也可以引用命令行定义的变量 范例:统计某个目录(如/root)下的文件占用的字节数(以MB显示): 分析:先执行ls命令显示出长信息,通过管道符运行awk,BEGIN设定变量,size=size+KaTeX parse error: Double superscript at position 80: …子目录,如何实现: 加入/^[^̲d]/就可以,匹配首行不是d的…n 当前记录(当前行)的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段$0 这个变量包含执行过程中当前行的文本内容FILENAME 当前输入文件的名FS 字段分隔符(默认是任何空格) NF 表示字段数,在执行过程中对应于当前的字段数NR 表示记录数,在执行过程中对应于当前的行号FNR 各文件分别计数的行号例1:NF:打印出每行有多少列: 何显示最后两列的值呢?分析:NF变量表示每行字段数,所以NF的值就是每行最后一个字段,NF减1就是倒数第二个字段。 例2:NR:每一行的行号: 例3:FNR:awk支持多文件扫描,如果采用NR, 下一个文件的行序号会接着上一个文件,FNR就会单独统计 例4:FS:分隔符用法:-F fs 其中fs是指定输入分隔符,fs可以是字符串或正则表达式;分隔符默认是空格 实列演示范例1:提取网卡的IP地址 分析:先用命令查看ip地址,通过管道符用grep通过牟定找到对应ip的行数,紧跟管道符锁定ip所在的第二列ip所在位置范例3:打印passwd文件中用户UID小于10的用户名和它登录使用的shell[root@localhost ~] # awk -F: ‘$3<10{print
1
"
<
=
=
=
=
=
>
"
1"<=====>"
1"<=====>"NF}’ /etc/passwd分析:指定:为分隔号,$3(uid)小于10符合要求打印出
1
(
用
户
名
)
1 (用户名)
1(用户名)NF登录shell范例4-:打印系统中能够正常登录的普通用户[root@localhost ~]# awk -F: ‘$3>=1000 && $NF=="/bin/bash"{print
1
,
1,
1,NF}’ /etc/passwd分析:指定:为分隔号,
3
(
u
i
d
)
大
于
等
于
1000
和
3(uid)大于等于1000和
3(uid)大于等于1000和NF等于/bin/bash的打印出用户名和登录shell 范例5:统计当前内存的使用率 说明:printf命令与print命令类似,用于显示输出的,只不过printf命令可以按照指定的格式显示输出。printf命令格式:printf “打印格式” 显示内容其中:%2.f就是打印格式,表保留小数后两位,f代表浮点数awk控制语句if语句if (条件) print if(条件){print}else{print}if(条件){print}else if(条件){print}else{print}范烈1:[root@localhost ~]# awk -F: ‘{if($3<1000) {print “system_user=”$1} else {print “program_user=”$1}}’ /etc/passwd分析:指定:为分隔符,当$3位置的uid小于1000打印出$1位置的用户名,如果不是同样也打印出用户名范烈2:[root@localhost ~]# df -hT | awk -F"[ %]+" ‘/^/dev/ {if($6>15)print $1,$6"%"}’ 说明: -F"[ %]+"表示将空格或%当做分隔符。if语句使用的地方===》对awk来说,要对取得的整行或某个字段做条件判断while循环语句:while(条件){语句} 如果条件为“真”进入循环,条件为“假”退出循环在进行运算结果统计时,可以使用符号+=,意思是说我们可以把增加的结果赋值给符号的左边的变量,对哪个域操作就把哪个域写在符号的右边,如Total+=$3范烈1:[root@localhost ~]# cat score.txt 姓名 性别 城市 科目 语文 数学 英语 总分 平均分马茵茵 女 上海 文科 85 94 70 249 83.00 刘俊 男 上海 理科 76 80 83 239 79.67 刘婷婷 女 广州 理科 83 88 81 252 84.00 汤洁冰 女 广州 理科 67 88 52 207 69.00 余小灵 男 天津 理科 93 90 87 270 90.00 [root@localhost ~]# awk ‘{total=total+$5}END{print "YuWen score:"total}’ score.txt YuWen score:503 分析:指定第五列设定变量,紧跟着打印出第五列的数字相加[root@localhost ~]# awk ‘{total+=KaTeX parse error: Expected 'EOF', got '}' at position 2: 5}̲END{print "YuWe…i;i++}; print total}’ b.txt 分析:先定义变量,total设定循环条件,i=1中的1相当于KaTeX parse error: Expected 'EOF', got '#' at position 120: …ot@localhost ~]#̲ awk '{total=0;…i}; print total}’ b.txt分析:先定义变量,total设定循环条件,i=1中的1相当于$1的1 i++是for的循环,每循环一次加一次分段的数据345957特殊作用:它能够用来遍历数组中的元素语法:for (var in array){语句}打印奇数或偶数行[root@localhost ~]# awk ‘NR%2==0{print NR,$0}’ /root/score.txt 分析:NR除2等于0的话打印出行数和整篇文章2 马茵茵 女 上海 文科 85 94 70 249 83.00 4 刘婷婷 女 广州 理科 83 88 81 252 84.00 6 余小灵 男 天津 理科 93 90 87 270 90.00 数组定义:简单来说,类似于标题下的小标题,这里面指的是abc :为数组名称[1]、[2]:为数组元素下标,可以理解为数组的第1个元素、数组的第2个元素”xiaohong”、”xiaolan”: 元素内容我们在引用数组变量的时候,必须要包含它的下标值,然后通过下标值来提取它相对应的元素值 [root@localhost ~]# awk 'BEGIN{> test[“a”]=“Mon”> test[“b”]=“Tue”> test[“c”]=“Wor”> print test[“b”]> }'显示结果:Tue也可以写成:# awk 'BEGIN{test[“a”]=“Mon”;test[“b”]=“Tue”;test[“c”]=“Wed”;print test[“b”]}'遍历数组中的元素这个时候可以使用for循环,for每一次循环的时候都会循环数组的下标,变量中存储的是下标值而不是元素值,for循环的作用是提取里面的下标值[root@localhost ~]# awk ‘BEGIN{> test[“a”]=“Mon”> test[“b”]=“Tue”> for(i in test)> {print “Index:“i,”-----value:“test[i]}> }'Index:a -----value:MonIndex:b -----value:Tue 删除数组[root@localhost ~]# awk 'BEGIN{test[1]=“a”;test[2]=“b”;for(i in test){print “Index:“i,”=====value:“test[i]}; delete test[2];print “---------”;for(i in test){print “Index:“i,”=====value:“test[i]}}'Index:1 =====value:aIndex:2 =====value:b---------Index:1 =====value:a统计listen和estableshed出现的次数分析:牟定tcp的,去除tcp6的行数,设定变量,字段++本身为0,for循环每执行一次+1,最后打印出下标值,也就是当个字段出现的次数 统计相同网站出现的次数[root@localhost mnt]# awk -F”[/]+” ‘{print $2}’ c.txt |sort|uniq -c5 www.163.com7 www.baidu.com1 www.cnblogs.com2 www.qq.com sort命令用于将文本文件内容加以排序uniq命令用于检查及删除文本文件中重复出现的行列,一般与sort命令结合使用。也可以通过下面的操作统计每个网站出现的次数:[root@localhost ~]# awk -F”[/]+” ‘{times[$2]++}END{for(i in times){print i,times[i]}}’ c.txt www.qq.com 2www.cnblogs.com 1www.baidu.com 7www.163.com 5脚本综合类似++++系统管理工具箱++++++h 显示命令帮助f 显示磁盘分区d 显示磁盘挂载m 查看内存使用u 查看系统负载q 退出程序 系统管理工具[root@localhost ~]# cat system.sh#!/bin/bashmenu(){cat<<eof++++系统管理工具箱++++++h 显示命令帮助f 显示磁盘使用情况d 显示磁盘挂载m 查看内存使用u 查看系统负载q 退出程序eof}#显示文件系统的磁盘使用情况统计Fdisk(){ df -Th}#显示硬盘容量、已使用容量、空闲容量Diskinfo(){ df -Th|awk '/^/dev/{print $1”\t\t”$3"\t\t\t"$4"\t\t\t"$5}’}#查看内存占用前10进程Memtop10(){ ps aux --sort -pmem | head -11 | awk ‘{print $1"\t"$2"\t"$4"\t"$11}’}#查看CPU占用前10进程Cputop10(){ ps aux --sort -pcpu|head -11|awk ‘{print $1"\t"$2"\t"$3"\t"$11}’}#显示帮助信息menuwhile truedo read -p “input a choose(h for help):” OP case $OP in h) clear menu;; f) echo “显示文件系统的磁盘使用情况统计” Fdisk;; d) echo “显示硬盘容量、已使用容量、空闲容量” Diskinfo;; m) echo “内存占用前10进程” Memtop10;; u) echo “CPU占用前10进程” Cputop10;; q) exit;; *) echo “输入错误” esacdone
shell
最新推荐文章于 2024-06-26 20:04:25 发布