linux之shell的一些基础

本文详细介绍了Shell脚本中的变量使用,包括位置参数、特殊变量以及局部和全局变量。接着讲解了条件判断,如数字比较和文件检查,并演示了逻辑操作符的用法。还深入探讨了循环结构,如for和while循环,以及如何跳出循环。此外,文章还涵盖了字符串处理、正则表达式、case语句、函数以及常见的文件处理命令。最后,通过实例展示了awk的使用,包括条件判断、循环和数组操作,以及如何利用awk进行数据统计。
摘要由CSDN通过智能技术生成

变量

 $1   执行脚本后跟的第一个位置参数
 $2   执行脚本后跟的第二个位置参数
 $3   执行脚本后跟的第三个位置参数
 $*   所有位置参数
 $0   当前所在的脚本名或进程
 $#   所有位置参数的个数
 $$   随机的进程号PID号,保存当前运行进程号
 $?   判断上一条指令是否执行成功,成功显示0,失败显示非0

局部变量 ,仅当前解释器进程中可以使用的变量

全局变量,解释器进程产生的子进程也可以使用的变量

export b=20 #定义一个 全局变量

export -n a #取消变量的全局效果

表达式

[root@test ~]# a=1
[root@test ~]# b=2
[root@test ~]# [ $a == $b ]  #变量前后两边都有空格
[root@test ~]# echo $?
1
$[  ]   计算
]# echo $[a+b]		#不需要空格

2.数字的条件判断 equal greater lesser than
-eq 是否相等 -ne 是否不等 -gt 是否大于
-ge 是否大于等于 -lt 是否小于 -le 是否小于等于

3.文件的条件、权限判断 加 ! 取反,带空格 ! -e

-e	判断文件是否存在,不关心文件类型
-f	判断文件是否存在且必须为文件
-d	判断文件是否存在且必须为目录
-r  -w判断当前用户对文件是否有读、写权限
-x 	判断当前用户对文件执行,目录是否能进入的权限

4.逻辑符号&& ||

&& 之前指令成功才执行之后的指令
||  之前指令失败才执行之后的指令
;  之前指令前后没有关系

单分支 if ;then fi

#!/bin/bash
if [ ! -d /opt/xyz ] ;then
        mkdir /opt/xyz
fi

双分支 if ;then else fi

#!/bin/bash
if [ ! -d /opt/xyz ] ;then
    mkdir /opt/xyz
  else
	mkdir /opt/abc
fi

多分支 elif… else

read -p "请输入你的成绩" n
if [ $n -ge 90 ];then
        echo "优秀"
	elif [ $n -ge 80 ];then
        echo "良好"
	elif [ $n -ge 60 ];then
        echo "及格"
	else
        echo "hehe"
fi

for 循环

#!/bin/bash
a=0
b=0
for i in {1..10}
do
   ping -c 3 -i 0.5 -W 1 192.168.4.$i &>/dev/null
   if [ 0 -eq $? ];then
        echo "192.168.4.$i tong"
        let a++
      else
        echo "192.168.4.$i bu tong"
        let b++
   fi
done
echo "$a台ok,$b台not ok"			

for循环嵌套

#!/bin/bash
for i in a b
do
   for j in x y
   do
     echo $i  $j
   done
done
##echo 四次  a x,a y,b x,b y

while循环,可以实现无限循环

#!/bin/bash
while [ 1 -eq 1 ]			#永远正确,while  ture
do
    	echo abc
    	sleep  1    #休息1秒
done
#!/bin/bash
x=1
while [ $x -le 5 ]     #通过条件测试决定执行任务的次数
do
    echo abc
    sleep 1
    let x++			#增长+1
done

exit 可以终止循环,但同时也终止整个脚本
break 可以终止循环,继续循环之后的任务
continue 可以终止当前循环,继续下一次循环

#!/bin/bash
x=0
while  :
do
read -p "求和,结束输入0 " n
       [ -z $n ] && echo "error" && continue   #空值时,要求重新输入
[ $n -eq 0 ] && break			#0时,终止输入
let x+=n
done
echo "和为:$x"

3.case 分支
功能类似if,不如if强大 语句比较精简。适合用来编写控制服务的工具

#!/bin/bash
case $1 in
a)
  echo aaa;;
b)
  echo bbb;;
*)
  echo "请输入a或b"
esac
]# bash case.sh b
bbb

shell函数

#!/bin/bash
colour(){
echo -e "\033[$1m$2\033[0m"
}
colour  31 abcd
colour  32 hehe
colour  33 xixi					#调用函数colour,$1 颜色 $2 内容,输出有颜色的内容
]# bash colour.sh

字符串处理

${变量名 : 截取的起始位 : 长度}

[root@test ~]# a=123456
[root@test ~]# echo ${a:2:2}
34
[root@test ~]# echo ${a:2:1}
3
[root@test ~]# echo ${a::1}
1

字符串的替换 ${变量名/old/new}

]# a=123123
]# echo ${a/2/6}			#替换第一个2
163123	
]# echo ${a//2/6}			#全部2替换
163163
]# echo ${a/2/}			#新内容不写时有删除作用
13123
]# echo ${a//2/}			#删除所有2
1313

字符串的删除

${ # } 从左往右掐头删除 ${ % } 从右往左去尾删除

]# a=123456
]# echo ${a#123}
456
]# a=abcdefghfd
]# echo ${a#*f}		# *f 任意字符到第一个f的字符串
ghfd
]# echo ${a##*f}		#   ##*f 删除到最后一个f
d

]# a=abcdefghfd
]# echo ${a%f*}   	#  删除尾部的f及后面所有
abcdefgh
[root@svr7 opt]# echo ${a%%f*}		#  %%*f 删除所有f
abcde

正则

^			匹配行首
$			匹配行尾
[]			集合,匹配集合中的任意单个亨符
[^]			对集合取反
.	   		匹配任意单个字符
\*				匹配前一个字符任意次数〔[*不允许单独使用]
\\{n,m\\ }	匹配前一个字符n到m次
\\{n\\}			匹配前一个字符n次
\\{n, \\ }		匹配前一个字符n次及以上
\\(\\)				保留
grep "root" user   		#找root     标准 带上" "
grep "[root]" user  	#找rot任意一个字符
grep "[rot]" user   	#效果同上
grep "[a-z]" user  	#找所有小写字母
grep "[A-Z]" user  	#找所有大写字母
grep "[a-Z]" user  	#找所有字母
grep "[0-9]" user 	 #找所有数字
grep "[^0-9]" user  	#找除了数字的内容,集合中[ ]的^代表取反
grep "[^a-Z0-9]" user  	#找特殊符号,非字母数字
grep "r..t" user   		#找rt之间有2个任意字符的行
grep "r...t" user  		#找rt之间有3个任意字符的行,没有匹配内容,就无输出	
grep "*" user  		#错误用法,*号是匹配前一个字符任意次,不能单独使用
grep "ro*t" user  		#找rt,中间的o有没有都行,有几次都行
grep "." user  		 #找任意单个字符,文档中每个字符都可以理解为任意字符
grep ".*" user  		#找任意,包括空行  相当于通配符*仅在正则表达式中这样写 .*
grep "ro\{1,2\}t" user    #找rt,中间的o可以有1~2个
grep "ro\{2,4\}t" user    #找rt,中间的o可以有2~4个
grep "ro\{2\}t" user    #找rt,中间的o只有2个
grep "ro\{3\}t" user    #找rt,中间的o只有3个
grep "ro\{3,\}t" user   #找rt,中间的o可以有3个以及3个以上
grep "ro\{1,\}t" user   #找rt,中间的o可以有1个以及1个以上

扩展正则列表 grep -E 、或 egrep

\+			最少匹配一次
?			最多匹配一次
{n,m}		匹配n到m次
()			组合为整体,保留或者
\\b			单词边界
egrep "ro{1,}t" user   	#egrep支持扩展正则,或者grep -E
egrep "ro+t" user     	#效果同上,最精简
grep "roo\{0,1\}t" user   #第二个o要出现0~1次
egrep "roo{0,1}t" user  #效果同上
egrep "roo?t" user   	#效果同上,最精简
grep "ro\{2\}t" user    #找o出现2次的
egrep "ro{2}t" user    	#效果同上
egrep "^root|^bin" user   #找root或者以bin开头的行
egrep "^(root|bin)" user   #效果同上

sed

选项: -n 屏蔽默认输出 -r 支持扩展正则 -i 写入文件

参数: p输出 d删除行 s替换 三个同符号# $ % ^即可做替换符

sed -n '1p' user	  #输出第1行
sed -n '2p' user    #输出第2行
sed -n '3p' user    #输出第3行
sed -n '2,4p' user   #输出第2~4行
sed -n '2,+1p' user  #输出第2行以及后面1行
sed -n '2p;4p' user  #输出第2行,第4行
sed -n '/^root/p' user  #在sed中使用/正则表达式/输出以root开头的行
sed -n 's/root/test/p' user		#替换每行的第一个root
sed -n 's/root/test/gp' /etc/passwd		#替换每行的所有root
sed 's#/bin/bash#/sbin/sh#' user  	#更换替换符号,三个同符号#  $  %  ^

高级使用

sed -n 's/.//p' test				#替换第1个字符为空
sed -n 's/.//2p' test			#替换第2个字符为空
sed -n 's/.//2; s/.$//p' test		#替换第2个、最后一个字符为空
sed -n 's/[0-9]//g'	test		#	找到任意数字,然后都替换为空	

( ) 保留,相当于复制 \1 代表粘贴

sed -r 's/([A-Z])/copy\1/g' test		#找到文档中所有行的所有大写字母,并在前面添加copy

a行下追加 i行上添加 c替换整行

sed 'a 666' test   #所有行的下面追加666
sed '1a 666' test  #第1行的下面追加666
sed '/root/a 666' test  #有root的行的下面追加666
sed 'i 666' test  #所有行的上面添加666
sed '1i 666' test  #第1行的上面添加666
sed '2i 666' test  #第2行的上面添加666
sed '/root/i 666' test  #有root的行的上面添加666
sed 'c 666' test  #替换所有行为666
sed '1c 666' test  #替换第1行为666
sed '/^bin/c 666' test  #替换以bin开头的行为666

awk常规使用
选项 -F 定义分隔符 指令 print
内置变量 $1第一列 $2第二列 $3 …. $0所有列 NR 行号 NF列号

awk '{print}' test.txt   	#输出所有行的内容
awk '/beijing/{print}' test.txt  #输出有beijing的行的内容
awk '/beijing$/{print}' test.txt  #输出以beijing结尾的行的内容
awk '{print $1}' test.txt  #输出所有行的第1列
awk '{print $3}' test.txt  #输出所有行的第3列
awk '/the/{print $3}' test.txt  #输出有the的行的第3列
awk '/the/{print NR}' test.txt   #输出有the的行的行号
awk '{print NR}' test.txt  #输出所有行的行号
awk '{print NF}' test.txt  #输出所有行的列号
awk '{print $0,NR}' test.txt  #输出所有列然后空格,输出行号
awk -F: '{print $1}' user   #使用-F:定义分隔符为冒号,输出第1列
awk -F: '{print $3}' user
awk -F: '{print $1" 的解释器是 "$7}' user   #输出常量用""

awk 过滤时机: BEGIN{ } { } END{ }

awk 'BEGIN{print "User\tUID\tHome"}'   #BEGIN任务,其中\t是可以实现tab键(空格、对其)的效果
awk -F: '{print $1"\t"$3"\t"$6}' user    #逐行任务
awk  'END{print "总计"NR"行"}' user  #END任务
将3个任务整合在一起
awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1"\t"$3"\t"$6}END{print "总计"NR"行"}' user

2.awk中的条件
1)使用正则作为条件
/ ^ / 为首 / $/ 结尾 ~ 包含 !~ 不包含

awk -F: '/bin/{print}' user    #输出含有bin的行,无论bin在第几列
awk -F: '$6~/bin/{print}' user  #输出第6列包含bin的行
awk -F: '$6!~/bin/{print}' user  #输出第6列不包含bin的行
awk -F: '$7=="/bin/bash"{print}' /etc/passwd   #对比内容不是变量,用双引号
awk -F: '$7!="/bin/bash"{print}' /etc/passwd  #上述情况的取反搜索

2)使用数字和字串作为条件
==相等 !=不相等 >大于 >=大于等于 <小于 <=小于等于

awk -F: 'NR==3{print}' /etc/passwd  #输出第3行
awk -F: 'NR<3{print}' /etc/passwd  #输出第1~2行
awk -F: '$3<10{print}' /etc/passwd  #输出id号是0~9的行
awk -F: '$3>=1000{print}' /etc/passwd  #输出普通用户的行

3)逻辑组合 && ||

awk -F: '$3>=10&&$3<=20' /etc/passwd  #找id号范围是10~20的行
awk -F: 'NR>=2&&NR<=10' /etc/passwd  #找2~10行
awk -F: '$3<5||$3>1000' /etc/passwd  #找id号是0~4或者1001以上的行
awk 'NR<5||NR>10{print NR}' /etc/passwd  #找1~4行或者11以上的行输出行号
awk -F: '$1=="root"||$1=="bin"' /etc/passwd  #找第1列是root或者bin的
awk -F: 'NR>5||NR<100' /etc/passwd   #找所有行
awk -F: 'NR<5&&NR>100' /etc/passwd   #逻辑错误,没有输出

4)使用运算±*/% ‘{print 1+1}’

awk 'BEGIN{print 1+1}'   #常规运算awk 'BEGIN{print 2-1}'
seq 200 | awk '$1%7==0'   #找到能被7整除的行 seq 10设置10行
seq 200 | awk '$1~/7/||$1%7==0'  #找被7整除或包含7的行
seq 200 | awk '$1~/7/&&$1%7==0'  #找被7整除并且包含7的行

awk中使用if
1)单分支awk ‘{if(条件){指令}}’ #格式,满足条件就执行

awk -F: '{if($7~/bash/){print}}'  user  #逐行处理,第7列包含bash,就输出该行

2)双分支,awk -F: ‘{if( ){ }else{ }}’
awk ‘{if(条件){指令}else{指令}}’ #基本格式
awk ‘{if( ){ }else{ }}END{ }’ #先写框架,多增加END任务

awk -F: '{if($7~/bash/){x++}else{y++}}END{print x,y}' /etc/passwd  #统计系统中使用bash和没有使用bash作为解释器的用户,的用户数量, 判断如果每找到一行的$7包含bash,就把x+1,否则y+1,最后使用end输出x与y的值

3)多分支,awk -F: ‘{if( ){ }else if( ){ }else{ }}’
awk ‘{if(条件){指令}else if(条件){指令}else{指令}}’ #基本格式
awk -F: ‘{if( ){ }else if( ){ }else{ }}END{ }’ #多增加END任务输出最终结果

awk -F: '{if($7~/bash/){x++}else if($7~/nologin/){y++}else{z++}}END{print x,y,z}' /etc/passwd  #找使用bash或者nologin作为解释器的账户数量,分别用变量x与y显示,其他解释器用z显示

4.awk中的for循环与数组,数组名[下标]
awk中的for循环:可以遍历数组(查看数组所有内容)for(变量名 in 需要遍历的数组名){执行任务} #变量在每次循环时,代表数组的不同下标
数组:相当于可以存储多个值的变量,数组名[下标]=某下标对应的值

awk 'BEGIN{a[1]=10;a[2]=20;print a[1]}'   #定义多个值,print a[1]输出该数组对应下标是1的值10
awk 'BEGIN{a[1]=10;a[2]=20;print a[2]}'			#20		
awk 'BEGIN{a[1]=10;a[2]=20;a[3]=30;print a[1],a[2],a[3]}'   #创建数组a,然后逐个输出
awk 'BEGIN{a[1]=10;a[2]=20;a[3]=30;for(i in a){print a[i]}}'  #使用for循环显示数组a的所有下标的值
awk 'BEGIN{a[1]=10;a[2]=20;a[3]=30;for(i in a){print i,a[i]}}'  #for循环遍历a数组下标与对应的值
1 10
2 20
3 30

使用awk的数组{a[$1]++}收集数据

[root@svr7 opt]# cat abc.txt0
abc
xyz
opq
abc
abc
xyz
awk '{a[$1]++}END{for(i in a){print a[i],i}}'  abc.txt #将$1收集到数组a中,累计次数,for循环显示所有内容

使用awk统计网站访问量:
tail -1 /var/log/httpd/access_log  #查看最后一条httpd访问日志
awk '{print $1}' /var/log/httpd/access_log    #  ip 第一列
awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' /var/log/httpd/access_log | sort -nr
#使用sort实现排序功能,-n是以数字作为排序对象,-r是降序

使用awk统计多少ip曾经尝试登陆你的服务器
tail -3 /var/log/secure   #查看安全日志,找到Failed password字样的行
awk '/Failed password/{ip[$11]++}END{for(i in ip){print ip[i],i}}' /var/log/secure
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值