7 流程控制 (重点)

​ 7.1 if 语句

​ 7.2 case语句

​ 7.3 for 循环

​ 7.4 while循环

8 read 读取控制台输入

9 函数

​ 9.1 系统函数

​ 9.2 自定义函数

10 Shell 工具(重点)

​ 10.1 cut

​ 10.2 sed

​ 10.3 awk

11 企业真实面试题

​ 11.1 京东

​ 11.2 搜狐&和讯网

​ 11.3 新浪

​ 11.4 金和网络


7 流程控制 (重点)

7.1 if 语句

  1. 基本语法
if [ 条件判断式 ]:then                左右必须有空格
   程序
fi
if [ 条件判断式 ]
	then
		程序
fi
if [ 条件判断式 ]
then
	程序
elif [ 条件判断式 ]
then
	程序
fi 
  1. 注意:
  • [ 条件判断式 ],中括号和条件判断式之间必须有空格
  • if后要有空格
  1. 实例
#!/bin/bash

if [ $1 -eq 1 ]
then
        echo "banzhang is handsome"
elif [ $1 -eq 2 ]
then
        echo "banzhang is beautiful"
fi
[fenfen@hadoop datas]$ bash if.sh 1
banzhang is handsome
[fenfen@hadoop datas]$ bash if.sh 2
banzhang is beautiful

7.2 case语句

  1. 基本语法:可以类比java的switch case break deflaut那一套
case $变量名 in
	"值1")
	程序
	;;
	"值2"
	程序
	;;
	*)
	剩余程序
	;;
rsac
  1. 案例
  • 输入一个数字,如果是1,则输出banzhang,如果是2,则输出fubanzhang,如果是其他,则输出同学
#!/bin/bash

case $1 in
1)
        echo "banzhang"
;;
2)
        echo "fubanzhang"
;;
*)
        echo "tongxue"
;;
esac
[fenfen@hadoop datas]$ bash case.sh 1
banzhang
[fenfen@hadoop datas]$ bash case.sh 2
fubanzhang
[fenfen@hadoop datas]$ bash case.sh 3
tongxue
[fenfen@hadoop datas]$ bash case.sh 4
tongxue

7.3 for 循环

  1. 基本语法:可以类比java的for循环,把括号改成do,done
for (( 初始值;循环控制条件;变量变化) 
	do 
		程序
	done
  1. 案例
  • 从1加到100
 #!/bin/bash

s=0
for(( i=1;i<=100;i++ ))		//为什么不用-eq不用=,因为=是赋值,-eq一般用在判断
do
        s=$[$s+$i]		//这边的前面的$[]是运算符的意思,$s和$i是变量
done

echo $s

[fenfen@hadoop datas]$ bash for.sh 
5050
  1. 第二种for语法:适用于离散的值
for 变量 in 值1 值2 值3
	do	
		程序
	done
  • 案例

打印输入的所有参数

#!/bin/bash

for i in $*
do
        echo "banzhang xihuan $i"       
done
[fenfen@hadoop datas]$ bash for2.sh lili meimei
banzhang xihuan lili
banzhang xihuan meimei

加入$@

#!/bin/bash

for i in $*
do
        echo "banzhang xihuan $i"       
done


for j in $@
do
        echo "banzhang xihuan $j"
done
[fenfen@hadoop datas]$ bash for2.sh lili meimei yingying
banzhang xihuan lili
banzhang xihuan meimei
banzhang xihuan yingying
banzhang xihuan lili
banzhang xihuan meimei
banzhang xihuan yingying

加个“”就不同了

#!/bin/bash

for i in "$*"
do
        echo "banzhang xihuan $i"       
done


for j in "$@"
do
        echo "banzhang xihuan $j"
done
[fenfen@hadoop datas]$ bash for2.sh lili meimei yingying
banzhang xihuan lili meimei yingying
banzhang xihuan lili
banzhang xihuan meimei
banzhang xihuan yingying

7.4 while循环

  1. 基本语法
while [ 条件判断式 ]
do
	程序
done
  1. 实例
  • 1+100
#!/bin/bash

s=0
i=1
while [ $i -le 100 ]
do
        s=$[$s+$i]
        i=$[$i+1]
done

echo $s
[fenfen@hadoop datas]$ bash while.sh 
5050

8 read 读取控制台输入

  1. 基本语法
read(选项)(参数)
选项:
-p:指定读取值时的提示符
-t:指定读取时等待的时间(秒)
参数:
变量:指定读取时的变量名
  1. 实例
  • 提示7 秒内,读控制台输入的名称
#!/bin/bash

read -t 7 -p "input your name " NAME

echo $NAME
[fenfen@hadoop datas]$ bash read.sh 
input your name fenfen
fenfen
[fenfen@hadoop datas]$ bash read.sh
input your name

9 函数

9.1 系统函数

  1. basename基本语法
basename [string/pathname(路径)][suffix]
  • 选项:suffix为后缀,如果suffix被指定了,basename会将pathname去掉suffix
  1. 功能
  • 删除所有的后缀包括最后一个('/')字符,然后将字符串显示出来
  • 干嘛用的啊:获取路径或者文件名称之后,可以赋值给到变量,做更多后续操作,实现自动化
  1. 实例
[fenfen@hadoop datas]$ basename /home/fenfen/datas/batch.sh 
batch.sh
[fenfen@hadoop datas]$ basename /home/fenfen/datas/parameter.sh 
parameter.sh
[fenfen@hadoop datas]$ basename /home/fenfen/datas/parameter.sh .sh
parameter
  1. dirname 基本语法
dirname 文件绝对路径
  • 功能:从给定的包含绝对路径的文件名中出去文件名(非目录的部分),然后返回剩下的路径(目录的部分)

  • 使用:basename和dirname一起使用

  1. 实例
[fenfen@hadoop datas]$ dirname /home/fenfen/datas/batch.sh 
/home/fenfen/datas

9.2 自定义函数

  1. 基本语法
[fuction] funname[()]
{
	Action;
	[return int;]//一般用$?,看语句反馈的状态
}
funname
  1. 注意点:
  • 必须在调用函数地方之前,先声明函数.shell脚本只会逐行运行。
  • 函数返回值,只能通过$?系统变量获得,可以显示加return,如果不加,就以最后一条命令运行结果,作为返回值。
  1. 实例
  • 计算两个输入参数的和
#!/bin/bash

function sum()
{
        s=0
        s=$[$1+$2]
        echo $s
}

read -p "input your parameter1:" P1        //第一个参数进来
read -p "input your parameter2:" P2

sum $P1 $P2					 //然后调用上面定义的sum函数,具体定义的$1与$2才是取参数值
[fenfen@hadoop datas]$ bash sum.sh 
input your parameter1:888
input your parameter2:666
1554

10 Shell 工具(重点)

10.1 cut

  1. 功能:剪,具体说就是在文件中负责剪数据用的。剪了是为了方便输出
  2. 基本用法:
cut [选项参数] filename
选项说明:
	-f:列好,提取第几列
	-d:分隔符,按照指定分隔符分割列,默认的分隔符是制表符
  1. 实例
  • 把第一列取出来
[fenfen@hadoop datas]$ vim cut.txt

guang nan
zhou jing
wo  wo
lai  lai
le  le

"cut.txt" 5L, 45C

[fenfen@hadoop datas]$ cut -d " " -f 1 cut.txt
guang
zhou
wo
lai
le
  • 取一下第2,3列
[fenfen@hadoop datas]$ cut -d " " -f 2,3 cut.txt
nan 
jing 
 wo
 lai
 le
  • 只要一个广(guang)字呢
[fenfen@hadoop datas]$ cat cut.txt | grep guang
guang nan 
[fenfen@hadoop datas]$ cat cut.txt | grep guang | cut -d " " -f 1 
guang
  • 选取系统PATH变量值,第五个":"开始后的所有路径
[fenfen@hadoop datas]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/local/jdk1.8.0_291/bin:/home/fenfen/.local/bin:/home/fenfen/bin


[fenfen@hadoop datas]$ echo $PATH | cut -d : -f 3-   //3-表示取3列后面的所有
/usr/local/sbin:/usr/sbin:/usr/local/jdk1.8.0_291/bin:/home/fenfen/.local/bin:/home/fenfen/bin

[fenfen@hadoop datas]$ echo $PATH | cut -d : -f 3
/usr/local/sbin 
  • 切个ip地址玩玩
[fenfen@hadoop datas]$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.60.102  netmask 255.255.255.0  broadcast 192.168.60.255
        inet6 fe80::20c:29ff:fea1:55c5  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:a1:55:c5  txqueuelen 1000  (Ethernet)
        RX packets 2546  bytes 201586 (196.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1536  bytes 208753 (203.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[fenfen@hadoop datas]$ ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.60.102  netmask 255.255.255.0  broadcast 192.168.60.255
        inet6 fe80::20c:29ff:fea1:55c5  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:a1:55:c5  txqueuelen 1000  (Ethernet)
        RX packets 2585  bytes 204474 (199.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1562  bytes 211807 (206.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


[fenfen@hadoop datas]$ ifconfig ens33 | grep "inet "
        inet 192.168.60.102  netmask 255.255.255.0  broadcast 192.168.60.255


[fenfen@hadoop datas]$ ifconfig ens33 | grep "inet "|cut -d " " -f 10
192.168.60.102

eth0的ip的cut过程

image.png

10.2 sed

  1. 功能:sed是一种流编辑器,它一次处理一行内容。当前处理的一行存储在临时缓冲区中,称为“模式空间”,处理好后再推送屏幕。
  2. 基本语法
sed [选项参数] 'command' filename
  1. 选项参数说明

​ -e:直接在命令列模式进行sed的动作编辑

  1. 命令功能描述

​ a:新增,后面跟字串,在下一行出现

​ d:删除

​ s:查找并替换 c:取代

  1. 案例
  • 将”believe“这个单词插入到sed.txt第二行下,并打印,但是原来的文件没有变
[fenfen@hadoop datas]$ sed "2a believe" sed.txt     或者sed -e 2a\believe sed.txt
guang nan
zhou jing
believe
wo  wo
lai  lai

le  le

[fenfen@hadoop datas]$ cat sed.txt 
guang nan
zhou jing
wo  wo
lai  lai

le  le
  • 删除sed.txt中所有包含wo的行
[fenfen@hadoop datas]$ sed "/wo/d" sed.txt    
guang nan
zhou jing
lai  lai

le  le
  • 将sed.txt中的wo替换成ni
[fenfen@hadoop datas]$ sed "s/wo/ni/g" sed.txt         //g表示全局替换
guang nan
zhou jing
ni  ni
lai  lai

le  le
  • 将sed.txt文件中的第二行删除并将我替换成ni
[fenfen@hadoop datas]$ sed -e "2d" -e "s/wo/ni/g" sed.txt
guang nan4
ni  ni
lai  lai

le  le

10.3 awk

正则表达式内容补充:(73条消息) 正则表达式全解析+常用示例_墨遥的博客-CSDN博客_正则表达式行尾

正则表达式测试网站Regex101的使用方法:正则表达式测试网站Regex101的使用方法 - 知乎 (zhihu.com)

用再去查,不行再学:【韩顺平讲Java】Java 正则表达式专题 -正则 正则表达式 元字符 限定符 Pattern Matcher 分组 捕获 反向引用等_哔哩哔哩_bilibili

  1. 功能:一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片, 切开的部分在进行分析处理

  2. 基本语法

awk [选项参数] 'pattern1{action1} pattern2{action2}...' filename

​ pattern:表示AWK在数据中查找的内容,匹配模式,相当于正则匹配

​ action:在找到匹配内容时所执行的命令

  1. 选项参数说明

​ -F:指定输入文件分隔符 F大写

​ -v:赋值一个用户定义变量 v小写

​ 内置变量 begin

​ FILENAME:文件名

​ NR:已读的记录数

​ NF:浏览记录的域的个数

  1. 案例
  • 搜索passwd文件以root关键字开头的所有行,并输出改行的第7列
    • /^正则开头
[fenfen@hadoop etc]$ sudo cp /etc/passwd ./
[fenfen@hadoop datas]$ sudo chown fenfen passwd
[fenfen@hadoop datas]$ sudo chgrp happy passwd
[fenfen@hadoop datas]$ ll
-rw-r--r-- 1 fenfen happy  1037 Jul 30 21:49 passwd
-rw-r--r-- 1 fenfen happy   62 Jul 26 18:06 read.sh
-rw-r--r-- 1 fenfen happy   44 Jul 30 21:04 sed.txt
[fenfen@hadoop datas]$ cat passwd
root:x:0:0:root:/root:/bin/bash

[fenfen@hadoop datas]$ awk -F : '/^root/{print $7}' passwd
/bin/bash
  • 搜索passwd文件以root关键字开头的所有行,并输出改行的第1列和第7列,中间以”,“号分割
[fenfen@hadoop datas]$ awk -F : '/^root/{print $1","$7}' passwd
root,/bin/bash
  • 显示passwd文件的第1列和第7列,以逗号分隔, 且在所有行前面添加列名user,shell在最后一行添加”fenfen,/bin/zuibang“
[fenfen@hadoop datas]$ awk -F : 'BEGIN{print "user,shell"} {print $1","$7} END{print "fenfen,bin/zuibang"}' passwd 
user,shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
halt,/sbin/halt
mail,/sbin/nologin
operator,/sbin/nologin
games,/sbin/nologin
ftp,/sbin/nologin
nobody,/sbin/nologin
systemd-network,/sbin/nologin
dbus,/sbin/nologin
polkitd,/sbin/nologin
sshd,/sbin/nologin
postfix,/sbin/nologin
hadoop,/bin/bash
mysql,/bin/false
fenfen,/bin/bash
tss,/sbin/nologin
fenfen,bin/zuibang
  • 将passwd文件中的用户id增加1并输出
[fenfen@hadoop datas]$ awk -F : -v i=1 '{print $3+i}' passwd        //-v 定义了一个变量
1
2
3
4
5
6
7
8
9
12
13
15
100
193
82
1000
75
90
1001
28
1002
60
  • 内置变量:统计passwd文件名,每行的行号,每行的列数
[fenfen@hadoop datas]$ awk -F : '{print FILENAME"," NR"," NF}' passwd
passwd,1,7
passwd,2,7
passwd,3,7
passwd,4,7
passwd,5,7
passwd,6,7
passwd,7,7
passwd,8,7
passwd,9,7
passwd,10,7
passwd,11,7
passwd,12,7
passwd,13,7
passwd,14,7
passwd,15,7
passwd,16,7
passwd,17,7
passwd,18,7
passwd,19,7
passwd,20,7
passwd,21,7
passwd,22,7
  • 切割ip
[fenfen@hadoop datas]$ ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.60.102  netmask 255.255.255.0  broadcast 192.168.60.255
        ether 00:0c:29:a1:55:c5  txqueuelen 1000  (Ethernet)
        RX packets 5834  bytes 462224 (451.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3699  bytes 447930 (437.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        
[fenfen@hadoop datas]$ ifconfig ens33 | grep "inet "
        inet 192.168.60.102  netmask 255.255.255.0  broadcast 192.168.60.255


[fenfen@hadoop datas]$ ifconfig ens33 | grep "inet " | awk -F " " '{print $2}'
192.168.60.102

eth0版本

image.png

  • 查询sed .txt中空行所在的行号
    • /^$正则:开头结尾没有内容就是空格
[fenfen@hadoop datas]$ awk '/^$/ {print NR}' sed.txt
5
[fenfen@hadoop datas]$ cat sed.txt

guang nan
zhou jing
wo  wo
lai  lai

le  le

10.4 sort

  1. 功能:sort命令在Linux中非常有用,他将文件进行排序,并将排序结果输出
  2. 基本语法
sort (选项) (参数)
选项:
-n 依照数值的大小排序
-r 以相反的顺序排序
-t 设置排序时所用的分割字符
-k 指定需要排序的列
  1. 实例
  • 按照第二列数值进行排序
[fenfen@hadoop datas]$ sort -t : -nrk 2 sort.sh
xz:50:2.3
bb:40:5.4
ss:30:1.6
bd:20:4.2
cls:10:3.5
[fenfen@hadoop datas]$ cat sort.sh 
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6

11 企业真实面试题

11.1 京东

  1. 使用Linux命令查询file1中空行所在的行号
[fenfen@hadoop datas]$ awk '/^$/{print NR}' file1
  1. 有文件chengji.txt内容如下

​ 张三 40

​ 李四 50

​ 王五 60

​ 使用Linux命令计算第二列的和并输出

[fenfen@hadoop datas]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'

11.2 搜狐&和讯网

  1. Shell脚本中如何检查一个文件是否存在?如果不存在改如何处理
[fenfen@hadoop datas]$ # vim 	a.sh
#!/bin/bash

if[ -f file.txt]
then
	echo "文件存在"
else
	echo "文件不存在"
fi

11.3 新浪

  1. 问题:用Shell写一个脚本,对文本无序的一列数字排序并累加求和
[fenfen@hadoop datas]$ cat test.txt
9
8
7
6
5
4
3
2
10
1
[fenfen@hadoop datas]$ sort -n test.txt | awk '{a+=$1;print$1}END{print "SUM="a}'

11.4 金和网络

  1. 问题:请用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”shen“的文件名称
[fenfen@hadoop datas]$ grep -r zhou /home
grep: /home/hadoop: Permission denied
/home/fenfen/datas/cut.txt:zhou jing 
/home/fenfen/datas/sed.txt:zhou jing


[fenfen@hadoop datas]$ grep -r zhou /home | cut -d ":" -f 1
grep: /home/hadoop: Permission denied
/home/fenfen/datas/cut.txt
/home/fenfen/datas/sed.txt