shell 使用总结-快速入门(二)

hello world!

	#!bin/Bash #标称这是shell脚本
	echo 'hello world!'

总览

	1. 提取文件中的行:grep
	2. 提取文件中的列:cut、awk、sed

正则表达式

	1. 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。grep、awk、sed等命令可以支持正则表达式。
	2. 通配符用来匹配符合条件的文件名,通配符是完全匹配。ls、find、cp这些命令不支持正则表达式,只能使用shell自己的通配符来进行匹配。

基础正则表达式

在这里插入图片描述

cut

cut [选项] 文件 #通过和grep通过管道配合使用取出需要的字段,但是不能识别多个空格的分隔符,只能识别指定字符比如分号、逗号、制表符等
	-f :列号   提取第几列
	-d :分隔符 按照指定分隔符分隔列,默认分隔符\t(制表符)
	文件:#stu.txt
	ID	name	gender	mark
	1	liming	m		12
	2	sc		m		34
	3	gao		m		36
	
执行:cut -f 2 stu.txt 
输出:
	name
	liming
	sc
	gao
	
执行:cut -f 1,2 stu.txt 
输出:
	1	name
	2	liming
	3	sc
	4	gao
	
cut -d ":" -f 1, 3 /etc/passwd #提取":"分隔后的 1, 3 列
cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ":" -f 1#显示etc/passwd,然后提取包含bin/bash文件,排除掉包含root的文件,然后通过":"进行列分隔,然后取出第一列

printf

	printf '输出类型输出格式' #awk常用的标准输出命令,因为awk不能调用系统命令echo(linux没有print,但是awk支持,区别是print会自动加\n)
	printf '输出类型输出格式' #%ns:输出n个字符组成的字符串 %ni:输出n个数字组成的整数 %m.nf:输出m位,其中有n位是小数点的浮点数
	printf '输出类型输出格式' #\a:警告 \b:退格,backsapce \f:清除屏幕 \n:换行 \r:回车 \t:水平输出退格,Tab tab \v:垂直输出退格,Tab

awk

eg:student.txt
	ID Name PHP Linux MySQL Average
	1 Liming 82 95 86 87.66
	2 Sc 74 96 87 85.66
	3 Gao 99 83 93 91.66
	
	awk '{printf $2 "\t" $6 "\n"}' student.txt #输出2、6列
	df -h | awk '{print $1 "\t" $3}'#输出1、3列
	awk 'BEGIN{printf "This is a transcript \n" } {printf $2 "\t" $6 "\n"}' student.txt #开头打印"This is a transcript
	awk 'END{printf "The End \n" } {printf $2 "\t" $6 "\n"}' student.txt #结尾打印The End 
	cat student.txt | grep -v Name | awk '$6 >= 87 {printf $2 "\n" }'

FS内置变量
	cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}' #提取1、3列

sed

1. sed[选项]'[动作]'  文件名 #对屏幕输出进行选取、替换、删除、新增的命令,是轻量级流控制编辑器
2. 选项:
	-n: 一般sed命令会把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕。
	-e: 允许对输入数据应用多条sed命令编辑
	-i: 用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出
3. 动作:
	a \: 追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。
	c \: 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结。
	i \: 插入,在当期行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。
	d: 删除,删除指定的行。
	p: 打印,输出指定的行。
	s: 字串替换,用一个字符串替换另外一个字符串。格式为"行范围s/旧字串/新字串/g"(和vim中的替换格式类似)。
# vi student.txt
	ID Name PHP Linux MySQL Average
	1 Liming 82 95 86 87.66
	2 Sc 74 96 87 85.66
	3 Gao 99 83 93 91.66	
	
	sed '2p' student.txt #查看文件的第二行
	sed -n '2p' student.txt
	sed '2,4d' student.txt #删除第二行到第四行的数据,但不修改文件本身
	sed '2a hello' student.txt #在第二行后追加 hello
	sed '2i hello world' student.txt #在第二行前插入两行数据
	sed '2c No such person‘ student.txt #数据替换
	
	sed 's/旧字串/新字串/g’ 文件名'
	sed '3s/74/99/g' student.txt 	#在第三行中,把 74 换成 99
	sed -i '3s/74/99/g' student.txt #sed操作的数据直接写入文件,源文件会改变
	sed -e 's/Liming//g ; s/Gao//g' student.txt #同时把"Liming"和"Gao"替换为空

sort

1. sort [选项] 文件名 
2. 选项:
	-f:忽略大小写
	-n:以数值型进行排序,默认使用字符串型排序
	-r:反向排序
	-t:指定分隔符,默认是分隔符是制表符
	-k n[,m]:按照指定的字段范围排序。从第n字段开始,m字段结束(默认到行尾)
	
	sort /etc/passwd # 排序用户信息文件	
	sort -r /etc/passwd # 反向排序
	sort -t ":" -k 3,3 /etc/passwd # 指定分隔符是“:”,用第三字段开头,第三字段结尾排序,就是只用第三字段排序
	sort -n -t ":" -k 3,3 /etc/passwd #指定为数值类型然后排序	

wc

1. wc [选项] 文件名 # 统计命令,显示行、单词数、字符数
2. 选项:
	-l:只统计行数
	-w:只统计单词数
	-m:只统计字符数

条件判断

1. 按照文件类型进行判断
	-d 文件 :判断该文件是否存在,并且是否为目录文件(是目录为真)
	-e 文件 :判断该文件是否存在(存在为真)
	-f 文件 :判断该文件是否存在,并且是否为普通文件(是普通文件为真)
		
	test -e /root/install.log
	[ -e /root/install.log ]#两边有空格,常用
	[ -d /root ] && echo "yes" || echo "no" # 第一个判断命令如果正确执行,则打印“ yes ”,否则打印“ no ”	
2. 按照文件权限进行判断
	-r 文件:判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真)
	-w文件:判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真)
	-x 文件:判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真)
	
	[ -w student.txt ] && echo "yes" || echo "no" # 判断文件是拥有写权限的
3. 两个文件之间进行比较
	文件1 -nt 文件2 :判断文件1的修改时间是否比文件2的新(如果新则为真)
	文件1 -ot 文件2 :判断文件1的修改时间是否比文件2的旧(如果旧则为真)
	文件1 -ef 文件2 :判断文件1是否和文件2的Inode号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法
	
	ln /root/student.txt /tmp/stu.txt # 创建硬链接
	[ /root/student.txt -ef /tmp/stu.txt ] && echo "yes" || echo "no"
yes# 用 test 测试
4. 两个整数之间比较
	整数1 -eq 整数2 : 判断整数1是否和整数2相等(相等为真)
	整数1 -ne 整数2 : 判断整数1是否和整数2不相等(不相等位置)
	整数1 -gt 整数2 : 判断整数1是否大于整数2(大于为真)
	整数1 -lt 整数2 : 判断整数1是否小于整数2(小于位置)
	整数1 -ge 整数2 : 判断整数1是否大于等于整数2(大于等于为真)
	整数1 -le 整数2 : 判断整数1是否小于等于整数2(小于等于为真)
	[ 23 -ge 22 ] && echo "yes" || echo "no" # 判断 23 是否大于等于 22 ,是
	[ 23 -le 22 ] && echo "yes" || echo "no" # 判断 23 是否小于等于 22 ,否
5. 字符串的判断
	-z 字符串 :判断字符串是否为空(为空返回真)
	-n 字符串 :判断字符串是否为非空(非空返回真)
	字串1 ==字串2 :判断字符串1是否和字符串2相等(相等返回真)
	字串1 != 字串2 :判断字符串1是否和字符串2不相等(不相等返回真)
	
	name=sc # 给 name 变量赋值
	[ -z "$name" ] && echo "yes" || echo "no" # 判断 name 变量是否为空,因为不为空,所以返回 no
	
	aa=11
	bb=22 # 给变量 aa 和变量 bb 赋值
	[ "$aa" == "bb" ] && echo "yes" || echo "no" # 判断两个变量的值是否相等,明显不相等,所以返回 no
6. 字符串的判断
	判断1 -a 判断2 : 逻辑与,判断1和判断2都成立,最终的结果才为真
	判断1 -o 判断2 : 逻辑或,判断1和判断2有一个成立,最终的结果就为真
	!判断 : 逻辑非,使原始的判断式取反	
	
	aa=11 
	[ -n "$aa" -a "$aa" -gt 23 ] && echo "yes" || echo "no" # 判断变量 aa 是否有值,同时判断变量 aa 的是否大于 23 ,因为变量 aa 的值不大于 23 ,所以虽然第一个判断值为真,返回的结果也是假	
	
	aa=24
	[ -n "$aa" -a "$aa" -gt 23 ] && echo "yes" || echo "no"

if 语句

1. 单分支if条件语句
	if [ 条件判断式 ];then
		程序
	fi

	if [ 条件判断式 ]
		then
		程序
	fi
	
注意事项	
	if语句使用fi结尾,和一般语言使用大括号结尾不同
	[ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格
	then后面跟符合条件之后执行的程序,可以放在[]之后,用";"分割。也可以换行写入,就不需要";"了
	
例子:判断分区使用率
	#!/bin/bash
	#统计根分区使用率
	rate=$(df -h | grep "/dev/sda3" | awk '{print $5}' | cut -d "%" -
	f1) #把根分区使用率作为变量值赋予变量 rate
	if [ $rate -ge 80 ]
		then
		echo "Warning! /dev/sda3 is full!!"
	fi
2. 双分支if条件语句
	if [ 条件判断式 ]
		then
		条件成立时,执行的程序
		else
		条件不成立时,执行的另一个程序
	fi
	
例子1:备份mysql数据库
	#!/bin/bash
	#备份 mysql 数据库。
	ntpdate asia.pool.ntp.org &>/dev/null 	#同步系统时间
	date=$(date +%y%m%d) #把当前系统时间按照“年月日”格式赋予变量 date
	size=$(du -sh /var/lib/mysql)#统计 mysql 数据库的大小,并把大小赋予 size 变量
	if [ -d /tmp/dbbak ]
		then
			echo "Date : $date!" > /tmp/dbbak/dbinfo.txt
			echo "Data size : $size" >> /tmp/dbbak/dbinfo.txt
			cd /tmp/dbbak
			tar  -zcf  mysql-lib-$date.tar.gz  /var/lib/mysql  dbinfo.txt 			&>/dev/null
			rm -rf /tmp/dbbak/dbinfo.txt
		else
			mkdir /tmp/dbbak
			echo "Date : $date!" > /tmp/dbbak/dbinfo.txt
			echo "Data size : $size" >> /tmp/dbbak/dbinfo.txt
			cd /tmp/dbbak
			tar  -zcf  mysql-lib-$date.tar.gz  /var/lib/mysql  dbinfo.txt 			&>/dev/null
			rm -rf /tmp/dbbak/dbinfo.txt
	fi

例子2:判断apache是否启动
	#!/bin/bash
	port=$(nmap -sT 192.168.1.156 | grep tcp | grep http | awk '{print 	$2}') 	#使用nmap命令扫描服务器,并截取apache服务的状态,赋予变量port
	if [ "$port" == "open" ]
		then
			echo$(date) httpd is ok!>> /tmp/autostart-acc.log
		else
			/etc/rc.d/init.d/httpd start &>/dev/null
		echo "$(date) restart httpd !!" >> /tmp/autostart-err.log
	fi	

3. 多分支if条件语句
	if [ 条件判断式1 ]
	then
	当条件判断式1成立时,执行程序1
	elif [ 条件判断式2 ]
		then
		当条件判断式2成立时,执行程序2
		省略更多条件 …
	else
	当所有条件都不成立时,最后执行此程序
	fi

	#!/bin/bash
	#判断用户输入的是什么文件
	read -p "Please input a filename: " file #接收键盘的输入,并赋予变量 file
	if [ -z "$file" ] #判断 file 变量是否为空
		then
			echo "Error,please input a filename"
			exit 1
	elif [ ! -e "$file" ] 	#判断 file 的值是否存在
		then
			echo "Your input is not a file!"
			exit 2
	elif [ -f "$file" ] 	#判断 file 的值是否为普通文件
		then
			echo "$file is a regulare file!"
	elif [ -d "$file" ] #判断 file 的值是否为目录文件
		then
			echo "$file is a directory!"
	else
			echo "$file is an other file!"
	fi

case 语句

多分支case条件语句
#case语句和if…elif…else语句一样都是多分支条件语句
#和if多分支条件语句不同,case语句只能判断一种条件关系
#if语句可以判断多种条件关系
格式:
	case $变量名 in 
	"值1")
		如果变量的值等于值1,则执行程序1
		;;
	"值2")
		如果变量的值等于值2,则执行程序2
		;;
		…省略其他分支…
		*)
		如果变量的值都不是以上的值,则执行此程序
		;;
	esac
	
	#!/bin/bash
	#判断用户输入
	read -p "Please choose yes/no: " -t 30 cho
	case $cho in
		"yes")
			echo "Your choose is yes!"
			;;
		"no")
			echo "Your choose is no!"
			;;
		*)
			echo "Your choose is error!"
			;;
	esac

for 循环

for 循环
格式1:
	for 变量 in 值1 值2 值3…
		do
			程序
		done
		
	#!/bin/bash
	#打印时间
	for time in morning noon afternoon evening
		do
			echo "This time is $time!"
		done
		
	#!/bin/bash
	#批量解压缩脚本
	cd /lamp
	ls *.tar.gz > ls.log
	for i in $(cat ls.log)
		do
			tar -zxf $i &>/dev/null
		done
	rm -rf /lamp/ls.log
	
格式2:
	for (( 初始值;循环控制条件;变量变化 ))
		do
		程序
	done

	#!/bin/bash
	# 从 1 加到 100
	s=0
	for (( i=1;i<=100;i=i+1 ))
		do
			s=$(( $s+$i ))
		done
	echo "The sum of 1+2+...+100 is : $s"

	#!/bin/bash
	read -p "Please input user name: " -t 30 name
	read -p "Please input the number of users: " -t 30 num
	read -p "Please input the password of users: " -t 30 pass
	if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ]
		then
		y=$(echo $num | sed 's/[0-9]//g')
			if [ -z "$y" ]
			then
			for (( i=1;i<=$num;i=i+1 ))
				do
					/usr/sbin/useradd $name$i &>/dev/null
					echo $pass | /usr/bin/passwd --stdin $name$i &>/dev/null
				done
		fi
	fi

while循环

while只要条件判断式成立,循环就会一直继续,直到条件判断式不成立.
格式:
	while [ 条件判断式 ]
		do
		程序
	done
	
	#!/bin/bash
	#从1加到100
	i=1
	s=0
	while [ $i -le 100 ]
		#如果变量 i 的值小于等于 100 ,则执行循环
		do
			s=$(( $s+$i ))
			i=$(( $i+1 ))
		done
	echo "The sum is: $s"

until循环

until循环和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。

格式:
	until [ 条件判断式 ]
		do
		程序
	done

	#!/bin/bash
	#从1加到100
	i=1
	s=0
	until [ $i -gt 100 ] #循环直到变量 i 的值大于 100 ,就停止循环
		do
			s=$(( $s+$i ))
			i=$(( $i+1 ))
		done
	echo "The sum is: $s"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值