一、Shell的基础语法

1、循环语句

1)for循环

  1. for 变量 in (list); do
  2. // 编写执行的语句
  3. done
  1. 1、遍历1~5
  2. #!/bin/bash
  3. for i in 1 2 3 4 5;do
  4. echo "当前的数字是$i";
  5. done
  6. 2、遍历1100的偶数
  7. 第一种写法:
  8. #!/bin/bash
  9. for i in {1..100}; do
  10. if [ $[i % 2] -eq 0 ]; then
  11. echo "偶数是$i"
  12. fi
  13. done
  14. for i in {1..100}; do
  15. if (( (i % 2) == 0 )); then
  16. echo "偶数是$i"
  17. fi
  18. done
  19. for i in {0..100..2}; do
  20. echo "偶数是$i"
  21. done
  22. 3、遍历查询出来的结果
  23. #!/bin/bash
  24. for i in `ls /root`; do
  25. echo $i
  26. done

image.png

2) while循环

  1. while 条件; do
  2. 执行语句
  3. done
  4. // 死循环
  5. while true; do
  6. 执行语句
  7. done
  1. 1~100之间相加
  2. #!/bin/bash
  3. i=1
  4. sum=0
  5. while [ $i -le 100 ]; do
  6. sum=$[ sum + i]
  7. ((i++))
  8. done
  9. echo $sum

image.png

  1. // 每隔一秒钟打印一个当前时间
  2. #!/bin/bash
  3. while true; do
  4. date
  5. sleep 1
  6. done

image.png

2、分支语句中的switch

语法

  1. case in
  2. 匹配的值1)
  3. 执行语句
  4. ;;
  5. 匹配的值2)
  6. 执行语句
  7. ;;
  8. esac

案例:

  1. 在控制台输入数据 1~7,如果是1 打印星期一
  2. #!/bin/bash
  3. echo "请输入1~7之间的数字"
  4. read num
  5. case $num in
  6. 1) echo "星期一"
  7. ;;
  8. 2) echo "星期二"
  9. ;;
  10. 3) echo "星期三"
  11. ;;
  12. 4) echo "星期四"
  13. ;;
  14. 5) echo "星期五"
  15. ;;
  16. 6) echo "星期六"
  17. ;;
  18. 7) echo "星期日"
  19. ;;
  20. esac

image.png

3、跳出循环(break contiune)

  1. break 跳出所有的循环
  2. continue 跳出本次循环
  1. 每隔1s打印时间,当打印到第10次的时候,跳出该循环
  2. #!/bin/bash
  3. i=1
  4. while true; do
  5. date
  6. sleep 1
  7. if [ $i -eq 10 ];then
  8. break
  9. fi
  10. ((i++))
  11. done

image.png

  1. continue 跳出本次循环,进入下一个循环
  2. 打印1~100之间不是10的倍数
  3. #!/bin/bash
  4. for i in {1..100}; do
  5. if test $[ i % 10 ] -eq 0; then
  6. continue
  7. fi
  8. echo $i
  9. done

4、函数(类似于java中的方法)

  1. function 方法名()
  2. {
  3. //执行语句
  4. [return xxx;]
  5. }

快速定义个方法,然后执行

  1. #!/bin/bash
  2. function showName()
  3. {
  4. echo "该方法被执行了"
  5. }
  6. showName

image.png

如何定义有参数的方法:

  1. function showName2()
  2. {
  3. echo "打印参数1 $1"
  4. echo "参数二是:$2"
  5. }
  6. showName2 1 100 1000

方法可以有返回值:
参数的返回: return 返回值

5、数组

  1. bash中,只支持一维数组,不支持多维数据。
  2. 数组的名字=(val1 val2 val3 ...)
  1. my_arr=(a b c d "E") 定义数组,并且赋值。
  2. //直接通过下标赋值
  3. my_arr2[0]=hello
  4. my_arr2[1]=world
  5. my_arr2[2]=java

image.png
数组的循环:
第一种方式类似于:foreach

  1. #!/bin/bash
  2. my_arr=(AA BB CC)
  3. for str in ${my_arr[*]}
  4. do
  5. echo $str
  6. done

第二种使用下标的方式

  1. #!/bin/bash
  2. my_arr=(AA BB CC)
  3. length=${#my_arr[*]}
  4. for((i=0;i<length;i++));
  5. do
  6. echo ${my_arr[$i]}
  7. done

合并起来的一个脚本是:

#!/bin/bash
echo "使用第一种方式循环:"
my_arr=(AA BB CC)
for str in ${my_arr[*]}
do
  echo $str
done

echo "使用第二种方式循环:"
length=${#my_arr[*]}
for((i=0;i<length;i++));
do
  echo ${my_arr[$i]}
done

6、脚本文件相互加载

a.sh 中定义了一个数组,b.sh中直接使用
a.sh中直接定义个数组

#!/bin/bash
echo "我是a脚本文件:"
my_arr=(AA BB CC)

b.sh中使用a.sh中的数组(使用之前要加载,类似于java中的导包)

#!/bin/bash
source ./a.sh  #加载文件中的内容

for str in ${my_arr[*]}
do
  echo $str
done

image.png

二、shell脚本的高级部分

grep 、 awk 、sed 号称是shell编程的三剑客

1、cut —提取,从命令结果中提取对应的内容

准备数据 1.txt

111:aaa:bbb:ccc
222:ddd:eee:fff
333:ggg:hhh
444:iii

cut 后面的 -c 的意思是按照字符选取内容

参数 英文 含义
-d ‘分隔符’ delimiter 指定分隔符
-f n1,n2 fields 分割以后显示第几段内容, 使用 , 分割
参数 英文 含义
-c characters 按字符选取内容

范围控制

范围 含义
n 只显示第n项
n- 显示 从第n项 一直到行尾
n-m 显示 从第n项 到 第m项(包括m)
1、提取1.txt中前两行的第五个字符
head -2 1.txt  // 查看文件的前两行
head -2 1.txt |  cut -c 5  

cut 本身也可以直接提取内容
cut -c 5 1.txt 

2、截取1.txt文件中前两行以:进行分割的1,2,3段内容
head -2 1.txt | cut -d ':' -f 1,2,3
head -2 1.txt | cut -d ':' -f 1-3

image.png

2、sort 排序

准备数据:2.txt

banana
apple
pear
orange
pear

对字符串进行排序,去重

参数 英文 含义
-u unique 去掉重复的

1、去重数据
image.png

2、数值类型操作
对数值类型进行的操作

参数 英文 含义
-n numeric-sort 按照数值大小排序
-r reverse 使次序颠倒

准备数据:3.txt

1
3
5
7
11
2
4
6
10
8
9

image.png
倒序:
image.png

3)对成绩进行排序

参数 英文 含义
-t field-separator 指定字段分隔符
-k key 根据那一列排序
造数据: 4.txt

zhangsan 68 99 26
lisi 98 66 96
wangwu 38 33 86
zhaoliu 78 44 36
maqi 88 22 66
zhouba 98 44 46

需求:根据第二个成绩进行倒序排序

cat 4.txt | sort -t ' ' -k 3

image.png

3、wc (wordcount)

wc 跟上文件名 显示文件的字节数,单词数,文件的行数
造数据:5.txt

111
222 bbb
333 aaa bbb 
444 aaa bbb ccc
555 aaa bbb ccc ddd
666 aaa bbb ccc ddd eee

image.png

如果只想显示某一些数据:

参数 英文 含义
-c bytes 字节数
-w words 单词数
-l lines 行数
wc -l  5.txt

wc -l  1.txt 2.txt 3.txt 4.txt 5.txt
wc -l  *.txt

image.png

我想看一下某个文件夹下有多少个文件

ls /etc  | wc -w
ll /etc | wc -l

4、awk(重点)

awk可以实现模糊查询,按需截取字符串,进行判断以及简单的运算

1)查询 搜索名字中含有zhang 和li 的学生成绩

命令 含义
awk ‘/搜索字符/‘ score.txt 模糊查询

模糊查询 ‘张三’ ‘张三三’

cat 4.txt | awk '/zhang|li/'
awk '/zhang|li/' 4.txt

2、指定分隔符,按照下标显示内容

命令 含义
awk -F ‘,’ ‘{print 2, $3}’ 文件 操作1.txt文件, 根据 逗号 分割, 打印 第一段 第二段 第三段 内容

选项

选项 英文 含义
-F ‘,’ field-separator 使用 指定字符 分割
$ + 数字 获取第几段内容
$0 获取 当前行 内容
NF field 表示当前行共有多少个字段
$NF 代表 最后一个字段
$(NF-1) 代表 倒数第二个字段
NR 代表 处理的是第几行

打印4.txt 中每个学生的姓名以及前两门的成绩

cat 4.txt | awk -F ' ' '{print $1,$2,$3}'

image.png

命令 含义
awk -F ‘ ‘ ‘{OFS=”===”}{print 2, $3}’ 1.txt 操作1.txt文件, 根据 逗号 分割, 打印 第一段 第二段 第三段 内容
选项 英文 含义
OFS=”字符” output field separator 向外输出时的段分割字符串

image.png

awk中使用函数

命令 含义
awk -F ‘,’ ‘{print toupper($2)}’ 1.txt 操作1.txt文件, 根据 逗号 分割, 打印 第一段 第二段 第三段 内容

常用函数如下:

函数名 含义 作用
toupper() upper 字符 转成 大写
tolower() lower 字符 转成小写
length() length 返回 字符长度


实战:

cat 4.txt | awk -F ' ' '{print toupper($1)}'

awk中还可以添加条件判断

cat 4.txt | awk -F ' ' '{if($4>60) print $1,$4}'
cat 4.txt | awk -F ' ' '{if($4>60) print $1,$4,"及格";else print $1,$4,"不及格"}'

image.png

awk中可以进行begin,end语句

命令 含义
awk ‘BEGIN{初始化操作}{每行都执行} END{结束时操作}’ 文件名 BEGIN{ 这里面放的是执行前的语句 }
{这里面放的是处理每一行时要执行的语句}
END {这里面放的是处理完所有的行后要执行的语句 }
//求最后一个成绩的总分
cat 4.txt | awk -F ' ' 'BEGIN{print "开始计算成绩总和"}{total=total+$4}END{print total}'

它是由三部分组成的
BEGIN{}  这一部分只执行一次
END{}    该代码块中的语句也只执行一次
中间{}   每读取一行数据,就执行一次

BEGIN 和 END 可以选择性的使用

// 获取记录条数:
cat 4.txt | awk -F ' ' 'BEGIN{print "开始计算成绩总和"}{total=total+$4}END{print total,NR}'

// 获取平均分
 cat 4.txt | awk -F ' ' 'BEGIN{print "开始计算成绩总和"}{total=total+$4}END{print total,NR,(total/NR)}'

5、sed操作 —实现过滤和替换

1、可以进行查询操作

命令 含义
sed 可选项 目标文件 对目标文件 进行 过滤查询替换

可选参数

可选项 英文 含义
p print 打印
$ 代表 最后一行
-n 仅显示处理后的结果
-e expression 根据表达式 进行处理

2、搞一些数据 6.txt

aaa java root
bbb hello
ccc rt
ddd root nologin
eee rtt
fff ROOT nologin
ggg rttt

3、列出6.txt中的3~5行的数据

cat 6.txt | sed -n -e '3,5p'

image.png
显示第一行到最后1行的数据:

cat 6.txt | sed -n -e '1,$p'

显示行号:

可选项 含义
= 打印当前行号

打印第三行到第五航的数据,显示行号

一种写法,没有使用sed ,而是使用了cat -n
cat -n 6.txt|sed -n -e '3,5p'

另一种写法:
sed -n -e '3,5=' -e '3,5p' 6.txt

image.png

sed进行查找:

// 需求是查找每一行中包含login的数据
cat 6.txt | sed -n -e '/login/p'
cat 6.txt| grep login

image.png
不区分大小写的查找,使用 I 参数
image.png

Sed 中可以使用正则表达式:

cat 6.txt|sed -n -r -e '/r+t/p'    
-r  后面可以跟正则表达式  +t  t字母出现一次到多次

image.png

Sed 进行删除操作:

先学习一个新命令 nl 可以查看文件,该文件自动添加行号
image.png
选项使用d 进行删除

显示除了3到5行的所有数据:
nl 6.txt | sed -e '3,5d'
nl 6.txt | sed -e '3,$d'  // 只显示前两行数据了

还可以使用sed修改内容

参数 英文 含义
i insert 目标前面 插入内容
a append 目标后面 追加内容
1、在6.txt的第一行前面插入 xxxxxxx,并显示行号

nl 6.txt | sed -e '1i xxxxxxxx'
2、在6.txt的第二行后面插入 SSSSSSS,并显示行号
nl 6.txt | sed -e '2a SSSSSSSS'

image.png

sed还可以进行数据的替换

s/oldString/newString/ replace 替换
把6.txt中的nologin替换成为huawei,并显示行号
cat  6.txt | sed  -e 's/nologin/huawei/'  // 按照字符串进行替换

cat  6.txt | sed  -e '3c laoyan'  // 按照行进行替换

image.png

以上的替换都是没有修改原来的数据的,sed也可以直接对原数据进行直接更改。
直接更改数据,首先数据进行备份

cp  6.txt  7.txt
sed -i -e 's/nologin/huawei/' 7.txt
sed -i -e '2c laoyanlaoyan' 7.txt
sed -i -e '1,2d' 7.txt  // 真删除数据

image.png

Sed综合练习:获取本机的IP地址

ifconfig  在 linux上可以获取本机的IP信息
ipconfig  在windows上可以获取IP地址信息

因为我们使用的是mini版,没有这个服务:
yum search ifconfig
yum install -y net-tools.x86_64
安装完毕就可以使用ifconfig 这个服务了。

image.png

符号 含义
^ 表示开始 ^aaa 表示以 aaa 开始
$ 表示结尾 bbb$ 表示以 bbb 结尾
.* 表示任意 ^.* 表示以 任意字符开始
需求是:通过ifconfig 命令获取我的IP地址
ifconfig ens33 | grep 'inet ' | sed -e 's/inet //' | sed -e 's/  netmask.*//'

6、split 文件切割

创造数据:拷贝一个/etc/services
cp /etc/services ~/
mv services big.txt
ll  查看文件的大小

按照字节进行切割:
split -b 100k big.txt
split -l 3000 big.txt

7、tr 替换和删除

tr  被替换的字符  新字符   是translate  的缩写

搞点数据:8.txt
laoyan
HELLO
abc12def34g

替换:
image.png
删除操作:
image.png

使用tr 进行一个单词计数的练习

9.txt


hello,world,hadoop
hive,sqoop,flume,hello
kitty,tom,jerry,world
hadoop
将单词中的,替换为换行符
cat 9.txt | tr ',' '\n'
//接着使用排序,去重等操作
cat 9.txt | tr ',' '\n' | sort | uniq 
// 接着可以进行单词重复记录的数据
cat 9.txt | tr ',' '\n' | sort | uniq -c

8、uniq 去重

uniq 命令用于检查及删除文本文件中重复出现的行,一般与 sort 命令结合使用

造一些数据10.txt

张三    98
李四    100
王五    90
赵六    95
麻七    70
李四    100
王五    90
赵六    95
麻七    70

cat 10.txt | sort | uniq

image.png

9、tee 可以将数据输送到各个文件中 ,跟一个水管一样

cat 10.txt | sort | uniq -c  | tee a.txt b.txt c.txt

image.png