Shell基础编程

1. 3种运行shell脚本的方式:

编辑一个shell脚本

后缀为 .sh 文件表示脚本文件

1
2
3
#!/bin/bash  这段代码的意思是:解释器(如果用sh命令来执行shell脚本,这行代码可以不必添加)

echo "你最帅"

1)通过sh命令运行shell脚本

1
2
[hadoop@hadoop001 shell]$ sh mand.sh 
你最帅

2)通过全路径执行shell脚本

首先我们需要先看一下这个脚本文件:

1
-rw-rw-r--. 1 hadoop hadoop   62 Apr 11 09:56 mand.sh

要通过全路径方式执行脚本,需要的要求:

①必须要赋予可执行的权限 x

1
chmod +x mand.sh

②脚本中的一行必须是

1
#!/bin/bash  (表示这个一个脚本)

执行结果如下:

1
2
[hadoop@hadoop001 shell]$ /home/hadoop/shell/mand.sh
你最帅

3) 通过当前路径执行脚本:

​ 这种执行方式的要求和全路径执行的要求是一样的。

① 赋予x权限

②脚本第一行:

1
#!/bin/bash

执行结果如下:

1
2
[hadoop@hadoop001 shell]$ /home/hadoop/shell/mand.sh
你最帅

进入debug模式:

1
2
3
4
5
#!/bin/bash -x

echo "你最帅"
echo "ruozedate"
echo `date`

也可以通过 sh +x mand.sh 命令来执行

执行结果:

1
2
3
4
5
6
7
8
9
10
[hadoop@hadoop001 shell]$ ./mand.sh
+ echo $'\344\275\240\346\234\200\345\270\205'
你最帅
+ echo ruozedate
ruozedate
++ date
+ echo Thu Apr 11 09:56:35 CST 2019
Thu Apr 11 09:56:35 CST 2019

+ 表示所执行的命令

2.变量的定义和引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
!#/bin/bash

RZ="ruozedare"

RD=`date`

echo ${RZ}
echo ${RD}

静态变量
K=V 'V' "V"

动态变量:表示shell脚本并不知道K的值,只有当运行到的一瞬间才会获取到值。
K=`V` 需要用反单引号

= 前后不能有空格

引用:$K和${K}两种方式都可以,但是$K 这种方式会存在坑
$KA:会将KA都当作变量,导致找不到准确的结果
${K}A

3.传递参数

1
2
3
4
5
6
7
8
9
10
11
!#/bin/bash

echo $1

echo $2

echo "个数:$#"

echo "传进参数作为一个长度字符串:$*"

echo "PID:$$"

执行结果:

1
2
3
4
5
6
[root@hadoop001 shell]# sh parameter.sh 5 a m
5
a
个数:3
传进参数作为一个长度字符串:5 a m
PID:4120

4.数组:

shell脚本中只支持一维数组
1
2
3
4
5
6
7
8
#!/bin/bash

array=(xiaoqiang xiaoxin yibao mili moumou) 数组中的内容需要用空格隔开

echo ${array[@]} @表示打印数组中的所有内容
echo ${array[*]} *表示打印数组中的所有内容
echo ${array[3]} 表示打印数组中索引为3的内容,索引从0开始
echo ${#array[@]} #表示个数

执行后结果:

1
2
3
4
5
6
[hadoop@hadoop001 shell]$ ./array.sh 

xiaoqiang xiaoxin yibao mili moumou
xiaoqiang xiaoxin yibao mili moumou
mili
5

5.if判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

A="abc"
B="bcd"

if [ ${A} == ${B} ];
then
echo "=="
elif [ "abd" == "abc"];
then
echo "字符串相等"
else
echo "!="
fi
注:[]中 A和B的前后都需要有空格

执行结果:

1
2
[hadoop@hadoop001 shell]$ sh if.sh 
字符串相等

6.循环:

for循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash


j=0
for x in 1 2 3 4 5
do
echo $x
let "j++"
done

echo ${j}

echo "---------------------------"

for ((i=0;i<=10;i++))
do
echo ${i}
done

let:表示运算

while循环:

1
2
3
4
5
6
7
8
9
10
x=1
y=0
while (($y<=10))
do
echo $y
let "y++"
let "x++"
done

echo $x

7.分割

1
2
3
4
5
6
7
8
9
10
11
12
A="xiaoqiang,xiaoxin,yibao,mili,moumou"   字符串

OLD_IFS="$IFS"
IFS="," 按,分割
arr=($A)
IFS="OLD_IFS"
以上是固定写法

for x in ${arr[*]} 通过遍历查看arr数组内容
do
echo "$x"
done

8.awk 取数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[hadoop@hadoop001 shell]$ cat awk.log |awk '{print $1}'  取第一列
1
4
7

[hadoop@hadoop001 shell]$ cat awk.log |awk '{print $2}' 取第二列
2
5
8

[hadoop@hadoop001 shell]$ cat awk.log |awk '{print $1 $2}' 取第一列和第二列
12
45
78

[hadoop@hadoop001 shell]$ cat awk.log |awk '{print $1,$2}' 取第一列和第二列
1 2
4 5
7 8

注:'{print $1 $2}'和'{print $1,$2}'区别(面试题)
'{print $1 $2}':表示先取第一列,然后取第二列。数据在文本中什么格式打印出来就是什么格式
'{print $1,$2}':表示先取第一行第一列,再取第一行第二列,再取第二行第一列

[hadoop@hadoop001 shell]$ cat awk.log |awk 'NR==1' 打印第一行
1 2 3
[hadoop@hadoop001 shell]$ cat awk.log |awk 'NR>1' 打印二三行
4 5 6
7 8 9

生产中日志里面数据的分隔符是按照某种规定分割的,并不是你所想要的这时候该怎么做

1
2
3
4
5
6
7
8
9
10
11
12
[hadoop@hadoop001 shell]$ cat awk.log |awk -F "," '{print $1,$2}'
1 2
4 5
7 8

-F 在这里表示 按逗号分割
注:后面 '{print $1,$2}' 必须是单引号,不能是双引号

如果想取第二行和第三行的第三列数据:
[hadoop@hadoop001 shell]$ cat awk.log |awk -F "," 'NR>1{print $3}'
6
9

另一种方式:

1
2
3
4
5
6
[hadoop@hadoop001 shell]$ awk -F "," '{print $1,$2}' awk.log 
1 2
4 5
7 8

以上的两种写法都一样,但是如果一个文件内容很多,用cat这种方式就不好了。

9.sed 替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[hadoop@hadoop001 shell]$ vi sed.log
a b c
1 2 3

[hadoop@hadoop001 shell]$ sed -i "s/a/aa/" sed.log
规范: -i 表示:替换文件内容 三个/ a表示文件之前的内容,aa替换后的内容
[hadoop@hadoop001 shell]$ cat sed.log
aa b c
1 2 3

如果要替换的数据中有单引号:最外层要用双引号而不能用单引号
[hadoop@hadoop001 shell]$ sed -i "s/aa/aa'/" sed.log
[hadoop@hadoop001 shell]$ cat sed.log
aa' b c
1 2 3

/也可以用?号代替
[hadoop@hadoop001 shell]$ sed -i "s?aa?bbb?" sed.log
[hadoop@hadoop001 shell]$ cat sed.log
bbb b c
1 2 3

**生产中用的最多**
如果你要将文件中的b全部替换成w,那么你就要在最后加一个 g 全局参数
[hadoop@hadoop001 shell]$ sed -i "s/b/w/g" sed.log
[hadoop@hadoop001 shell]$ cat sed.log
www w c
1 2 3

如果想要在每行的行首加字符:
[hadoop@hadoop001 shell]$ sed -i "s/^/uuu&/g" sed.log
[hadoop@hadoop001 shell]$ cat sed.log
uuuwww w c
uuu1 2 3

如果想在每行的行尾加字符:
[hadoop@hadoop001 shell]$ sed -i "s/$/mmm&/g" sed.log
[hadoop@hadoop001 shell]$ cat sed.log
uuuwww w cmmm
uuu1 2 3mmm

本文标题:Shell基础编程

文章作者:skygzx

发布时间:2019年04月11日 - 09:11

最后更新:2019年04月12日 - 20:10

原始链接:http://yoursite.com/2019/04/11/shell基础编程/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------本文结束感谢您的阅读-------------
0%