2019年12月16日shell 笔记
一、Shell中的数组
创建数组:
空数据: arr=()
Shell 数组用括号表示,元素用”空格”分割开
格式:非空数据: arr=(1 2 3 4) (带值;元素以空格分割)
注意: 往数组里添加值,数组的长度自动增长
实例:
创建空数据:
[heyali@jinghang ~]$ arr=()
创建非空数据:直接赋值
第一种:[heyali@jinghang ~]$ arr=(1 3 4 5 6 7)
第二种:下标定义数组
[heyali@jinghang ~]$ arr1=()
[heyali@jinghang ~]$ arr1[0]=1
[heyali@jinghang ~]$ arr1[1]=2
[heyali@jinghang ~]$ arr1[2]=3
[heyali@jinghang ~]$ arr1[3]=4
读取数组:
1、[heyali@jinghang ~]$ echo ${arr[1]}
3
2、
[heyali@jinghang ~]$ bash arry.sh
a
b
c
d
e
hello
word
3、
[heyali@jinghang ~]$ chmod +x arr2.sh
[heyali@jinghang ~]$ ./arr2.sh
获取数组中所有元素:
使用或@可以获取数组中所有元素
1、
[heyali@jinghang ~]$ echo ${arr1[]}
1 2 3 4
2、
[heyali@jinghang ~]$ echo ${arr1[@]}
1 2 3 4
获取数组长度:(* 或 @ 都可以)
获取数组长度的方法与获取字符串长度的方法相同
[heyali@jinghang ~]$ echo ${#arr1[*]}
4
遍历数组:
“hello word”:字符串要用双引号引起来
#!/bin/bash
arr1=(a b c d e “hello word”)
for i in ${arr1[]}
do
echo $i
done
echo ${#arr1[]}
二、运算符
(1)“( ( 运 算 式 ) ) ” 或 “ ((运算式))”或“((运算式))”或“[运算式]” + , - , *, /, % 加,减,乘,除,取余
(2)expr + , - , *, /, % 加,减,乘,除,取余
注意:expr运算符间要有空格
第一种:(())
[heyali@jinghang ~]$ a=1
[heyali@jinghang ~]$ b=2
[heyali@jinghang ~]$ echo ( ( ((((b-a ) ) 1 [ h e y a l i @ j i n g h a n g ] a)) 1 [heyali@jinghang ~]a))1[heyali@jinghang ] echo ( ( ((((b+a ) ) 3 [ h e y a l i @ j i n g h a n g ] a)) 3 [heyali@jinghang ~]a))3[heyali@jinghang ] echo ( ( ((((b*a ) ) 2 [ h e y a l i @ j i n g h a n g ] a)) 2 [heyali@jinghang ~]a))2[heyali@jinghang ] echo ( ( ((((b/a ) ) 22 、 第 二 种 [ ] [ h e y a l i @ j i n g h a n g ] a)) 2 2、第二种 [] [heyali@jinghang ~]a))22、第二种[][heyali@jinghang ] echo [ [[b*$a]
2
(1)expr:一步完成计算
[heyali@jinghang ~]$ expr expr 2 + 3
* 4
20
(2)采用[ 运 算 式 ] 方 式 [ h e y a l i @ j i n g h a n g ] [运算式]方式 [heyali@jinghang ~][运算式]方式[heyali@jinghang ] S=[ ( 2 + 3 ) ∗ 4 ] [ h e y a l i @ j i n g h a n g ] [(2+3)*4] [heyali@jinghang ~][(2+3)∗4][heyali@jinghang ] echo $S
20
小数之间的运算(scale 小数点后几位,只对除法有效)
[heyali@jinghang ~]$ b=1.33
[heyali@jinghang ~]$ c=5
[heyali@jinghang ~]$ echo $(echo “scale=1; b / b/b/c” | bc)
.2
三、条件判断
1、基础语法:
[ condition ](注意condition前后要有空格)
注意:条件非空即为true,[ jinghnag ]返回true,[] 返回false。
[heyali@jinghang ~]$ [ 1 ]
[heyali@jinghang ~]$ echo ? 0 [ h e y a l i @ j i n g h a n g ] ? 0 [heyali@jinghang ~]?0[heyali@jinghang ] echo $?
1
2、常用判断条件
(1)两个整数之间比较
= 字符串比较
-lt 小于(less than) -le 小于等于(less equal)
-eq 等于(equal) -gt 大于(greater than)
-ge 大于等于(greater equal) -ne 不等于(Not equal)
(2)按照文件权限进行判断
-r 有读的权限(read) -w 有写的权限(write)
-x 有执行的权限(execute)
(3)按照文件类型进行判断
-f 文件存在并且是一个常规的文件(file)
-e 文件存在(existence) -d 文件存在并是一个目录(directory)
实例:
-ge 大于等于(greater equal)
[heyali@jinghang ~]$ [ 23 -ge 22 ]
[heyali@jinghang ~]$ echo $?
0
-w 有写的权限(write)(arry.sh是否有写的权限)
[heyali@jinghang ~]$ [ -w arry.sh ]
[heyali@jinghang ~]$ echo $?
0
/home/jinghang/cls.txt 目录中的文件是否存在
[heyali@jinghang ~]$ [ -e /home/jinghang/cls.txt ]
[heyali@jinghang ~]$ echo $?
1
多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
[heyali@jinghang ~]$ [ condition ] && echo OK || echo notok
OK
[heyali@jinghang ~]$ [ condition ] && [ ] || echo notok
notok
四、流程控制
If判断:
1.基本语法
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
注意事项:
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
(2)if后要有空格
如果aaa.txt文件存在,往文件中写入bbb,如果不存在,创建aaa.txt文件,往文件中写入bbb
#!/bin/bash
if [ -f aaa.txt ]
then
echo “该文件存在”
echo “bbb” >> aaa.txt
else
echo “该文件不存在”
touch aaa.txt
echo “bbb” >> aaa.txt
fi
注意:if和elif后需要有空格
Case语句
基本语法:
case 变 量 名 i n " 值 1 " ) 如 果 变 量 的 值 等 于 值 1 , 则 执 行 程 序 1 ; ; " 值 2 " ) 如 果 变 量 的 值 等 于 值 2 , 则 执 行 程 序 2 ; ; … 省 略 其 他 分 支 … ∗ ) 如 果 变 量 的 值 都 不 是 以 上 的 值 , 则 执 行 此 程 序 ; ; e s a c 注 意 事 项 : 1 ) c a s e 行 尾 必 须 为 单 词 “ i n ” , 每 一 个 模 式 匹 配 必 须 以 右 括 号 “ ) ” 结 束 。 2 ) 双 分 号 “ ; ; ” 表 示 命 令 序 列 结 束 , 相 当 于 j a v a 中 的 b r e a k 。 3 ) 最 后 的 “ ∗ ) ” 表 示 默 认 模 式 , 相 当 于 j a v a 中 的 d e f a u l t 。 注 意 : c a s e 相 当 于 j a v a 中 的 s w i t c h " 1 " ) 相 当 于 s w i t c h 中 的 c a s e " 1 " : ∗ ) 相 当 于 s w i t c h 中 的 d e f a u l t ; ; 相 当 于 s w i t c h 相 当 于 b r e a k 结 尾 e s a c 实 例 : 输 入 一 个 数 字 , 如 果 是 1 , 则 输 出 y i n y e , 如 果 是 2 , 则 输 出 c l s , 如 果 是 其 它 , 输 出 t i y u 。 [ h e y a l i @ j i n g h a n g ] 变量名 in "值1") 如果变量的值等于值1,则执行程序1 ;; "值2") 如果变量的值等于值2,则执行程序2 ;; …省略其他分支… *) 如果变量的值都不是以上的值,则执行此程序 ;; esac 注意事项: 1)case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。 2)双分号“;;”表示命令序列结束,相当于java中的break。 3)最后的“*)”表示默认模式,相当于java中的default。 注意:case 相当于java中的switch "1") 相当于switch 中的 case "1": *) 相当于switch 中的default ;; 相当于switch 相当于break 结尾 esac 实例: 输入一个数字,如果是1,则输出yinye,如果是2,则输出cls,如果是其它,输出tiyu。 [heyali@jinghang ~]变量名in"值1")如果变量的值等于值1,则执行程序1;;"值2")如果变量的值等于值2,则执行程序2;;…省略其他分支…∗)如果变量的值都不是以上的值,则执行此程序;;esac注意事项:1)case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。2)双分号“;;”表示命令序列结束,相当于java中的break。3)最后的“∗)”表示默认模式,相当于java中的default。注意:case相当于java中的switch"1")相当于switch中的case"1":∗)相当于switch中的default;;相当于switch相当于break结尾esac实例:输入一个数字,如果是1,则输出yinye,如果是2,则输出cls,如果是其它,输出tiyu。[heyali@jinghang ] vim case.sh
[heyali@jinghang ~]$ chmod 777 case.sh
[heyali@jinghang ~]$ ./case.sh
tiyu
[heyali@jinghang ~]$ ./case.sh 1
yinyue
for循环
基本语法:
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
实例:从1加到100
[heyali@jinghang ~]$ vim if3.sh
[heyali@jinghang ~]$ touch for.sh
[heyali@jinghang ~]$ vim for.sh
[heyali@jinghang ~]$ chmod 777 for.sh
[heyali@jinghang ~]$ ./for.sh
5050
基本语法2
for 变量 in 值1 值2 值3…
do
程序
done
实例:打印所有输入参数
[heyali@jinghang ~]$ touch for2.sh
[heyali@jinghang ~]$ vim for2.sh
[heyali@jinghang ~]$ chmod 777 for2.sh
[heyali@jinghang ~]$ bash for2.sh cls xz bd
yinyue cls
yinyue xz
yinyue bd
比较∗ 和 *和∗和@区别
∗ 和 *和∗和@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 2 … 2 …2…n的形式输出所有参数。
[heyali@jinghang ~]$ bash for1.sh cls xz bd
yinyue cls
yinyue xz
yinyue bd
yinyue cls
yinyue xz
yinyue bd
当它们被双引号“”包含时,“$*”会将所有的参数作为一个整体,以“$1 2 … 2 …2…n”的形式输出所有参数;“$@”会将各个参数分开,以“$1” “2 ” … ” 2”…”2”…”n”的形式输出所有参数。
[heyali@jinghang ~]$ bash for1.sh cls xz bd
yinyue cls xz bd
yinyue cls
yinyue xz
yinyue bd
While循环
基本语法:
while [ 条件判断式 ]
do
程序
done
实例:从1加到100
[heyali@jinghang ~]$ touch while.sh
[heyali@jinghang ~]$ vim while.sh
[heyali@jinghang ~]$ chmod 777 while.sh
[heyali@jinghang ~]$ ./while.sh
5050
五、read读取控制台输入
基本语法:
read(选项)(参数)
选项:
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
参数
变量:指定读取值的变量名
实例:
提示7秒内,读取控制台输入的名称
[heyali@jinghang ~]$ touch read.sh
[heyali@jinghang ~]$ vim read.sh
[heyali@jinghang ~]$ chmod 777 read.sh
#!/bin/bash
read -t 7 -p “Enter your name in 7 seconds” NAME
echo N A M E [ h e y a l i @ j i n g h a n g ] NAME [heyali@jinghang ~]NAME[heyali@jinghang ] ./read.sh
Enter your name in 7 seconds qqqqqq
六、函数
系统函数:
1、basename基本语法
basename [string / pathname] [suffix] (功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
选项:
suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
实例:
截取该/home/jinghnag/banzhang.txt路径的文件名称
[heyali@jinghang ~]$ basename /home/jinghang/a.txt
a.txt
[heyali@jinghang ~]$ basename /home/jinghang/a.txt .txt
a
2、dirname基本语法
dirname 文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
实例:获取banzhang.txt文件的路径
[heyali@jinghang ~]$ dirname /home/jinghang/a.txt
/home/jinghang
自定义函数
基本语法:
[ function ] funname[()]
{
Action;
[return int;]
}
funname
注意:(1)必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
(2)函数返回值,只能通过? 系 统 变 量 获 得 , 可 以 显 示 加 : r e t u r n 返 回 , 如 果 不 加 , 将 以 最 后 一 条 命 令 运 行 结 果 , 作 为 返 回 值 。 r e t u r n 后 跟 数 值 n ( 0 − 255 ) 实 例 : [ h e y a l i @ j i n g h a n g ] ?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255) 实例: [heyali@jinghang ~]?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0−255)实例:[heyali@jinghang ] touch fun.sh
[heyali@jinghang ~]$ vim fun.sh
#!/bin/bash
function sum()
{
s=0
s=$[ $1 + 2 ] e c h o " 2 ] echo "2]echo"s"
}
read -p "please input the number1: " n1;
read -p "please input the number2: " n2;
sum $n1 n 2 ; [ h e y a l i @ j i n g h a n g ] n2; [heyali@jinghang ~]n2;[heyali@jinghang ] chmod 777 fun.sh
[heyali@jinghang ~]$ ./fun.sh
please input the number1: 2
please input the number2: 8
10
七、shell工具(文本处理工具)
1、Cut
cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
基本数据:
cut [选项参数] filename
说明:默认分隔符是制表符
选项参数:
选项参数 功能
-f 列号,提取第几列
-d 分隔符,按照指定分隔符分割列
-c 指定具体的字符
实例:
准备数据:
[heyali@jinghang ~]$ touch cut.txt
[heyali@jinghang ~]$ vim cut.txt
切割cut.txt 第一列
[heyali@jinghang ~]$ cut -d " " -f 1 cut.txt
zhong
ying
feng
tian
ming
切割cut.txt第二、三列
[heyali@jinghang ~]$ cut -d " " -f 2,3 cut.txt
guo
guo
jing
yuan
mei
在cut.txt文件中切割出guo
[heyali@jinghang ~]$ cat cut.txt | grep “guo” | cut -d " " -f 1
zhong
ying
2、sed
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
基本用法:
sed [选项参数] ‘command’ filename
选项参数说明:
选项参数 功能
-e 直接在指令列模式上进行sed的动作编辑。
-i 直接编辑文件
命令功能描述:
命令 功能描述
a 新增,a的后面可以接字串,在下一行出现
d 删除
s 查找并替换
实例:
数据准备:
[heyali@jinghang ~]$ touch sed.txt
[heyali@jinghang ~]$ vim sed.txt
zhong guo
ying guo
mei guo
ai ji
yin du
zhi li
将“mei nv”这个单词插入到sed.txt第二行下,打印
[heyali@jinghang ~]$ sed ‘2a mei nv’ sed.txt
zhong guo
ying guo
mei nv
mei guo
ai ji
yin du
zhi li
[heyali@jinghang ~]$ cat sed.txt
zhong guo
ying guo
mei guo
ai ji
yin du
zhi li
文件并没有改变
删除sed.txt文件所有包含ai的行
[heyali@jinghang ~]$ sed ‘/ai/d’ sed.txt
zhong guo
ying guo
mei guo
yin du
zhi li
将sed.txt文件中zhi替换为ni
[heyali@jinghang ~]$ sed ‘s/zhi/ni/g’ sed.txt
zhong guo
ying guo
mei guo
ai ji
yin du
ni li
注意:‘g’表示global,全部替换
将sed.txt文件中的第二行删除并将mei替换为ni
[heyali@jinghang ~]$ sed -e ‘2d’ -e ‘s/mei/ni/g’ sed.txt
zhong guo
ni guo
ai ji
yin du
zhi li
3、awk
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
基本用法:
awk [选项参数] ‘pattern1{action1} pattern2{action2}…’ filename
pattern:表示AWK在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
选项参数:
选项参数 功能
-F 指定输入文件折分隔符
-v 赋值一个用户定义变量
正则表达式
. 匹配除了换行符之外的任意字符
\d 匹配数字0-9 => [0-9]
\D 匹配非数字 => [^0-9]
\s 匹配空白字符(空格 \t \n …)
\S 匹配非空白字符
\w 匹配单词字符([a-zA-Z0-9_])
\W 匹配非单词字符
^ 匹配以…开头
$ 匹配结尾
多字符匹配(贪婪匹配)
.* 匹配*号前的字符任意次数 aaabbbccc a*?
.+ 匹配+号前的字符至少一次
.? 匹配?号前的字符0~1次
多字符匹配(非贪婪匹配)
.*?
.+?
.??
其他
|
() 分组
实例:
数据准备:
命令:
cat passwd | awk -F : ‘/^root/{print $1"-"$3}’
结果:
root-0
cat passwd | awk -F : '/^root|^jinghang/{print $1"-"$3}'
root-0
jinghang-500
cat passwd | awk -F : '/^root/{print $1"-"$3} /^jinghang/{print $1"-"$3}'
root-0
jinghang-500
awk -F : 'BEGIN{sum=0}{sum+=1;print $1","sum}END{print sum}' passwd
awk -F : '$3 > 100' passwd
awk -v sum=0 -F : '{sum+=1;print $1","sum}END{print sum}' passwd
awk内置变量的使用
FILENAME 文件名
NR 已读的记录数
NF 浏览记录的域的个数(切割后,列的个数)
awk -F : '{print "filename:"FILENAME",lines:"NR",colums:"NF}' passwd
使用awk提取ip地址
cat if | grep Bcast | awk -F : '{print $2}' | awk -F " " '{print $1}'
获取文件空行的行号
cat if | awk '/^$/{print NR}'
获取文件空行的总行数
cat if | awk '/^$/{print NR}' | wc -l
4、sort
sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。
基本语法:
sort(选项)(参数)
选项 说明
-n 依照数值的大小排序
-r 以相反的顺序来排序
-t 设置排序时所用的分隔字符
-k 指定需要排序的列
参数:指定待排序的文件列表
实例:
准备数据:
[heyali@jinghang ~]$ touch sort.sh
[heyali@jinghang ~]$ vim sort.sh
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
按照“:”分割后的第三列倒序排序。
[heyali@jinghang ~]$ sort -t : -nrk 3 sort.sh
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6
题:
问题1:获取随机字符串(8位)
答案:
[jinghnag@hadoop101 datas]$ echo $RANDOM |md5sum |cut -c 1-8
问题1:使用Linux命令查询file1中空行所在的行号
答案:
[jinghnag@hadoop101 datas]$ awk '/^/ p r i n t N R ′ s e d . t x t 5 问 题 2 : 有 文 件 c h e n g j i . t x t 内 容 如 下 : 张 三 40 李 四 50 王 五 60 使 用 L i n u x 命 令 计 算 第 二 列 的 和 并 输 出 [ j i n g h n a g @ h a d o o p 101 d a t a s ] /{print NR}' sed.txt 5 问题2:有文件chengji.txt内容如下: 张三 40 李四 50 王五 60 使用Linux命令计算第二列的和并输出 [jinghnag@hadoop101 datas]/printNR′sed.txt5问题2:有文件chengji.txt内容如下:张三40李四50王五60使用Linux命令计算第二列的和并输出[jinghnag@hadoop101datas] cat chengji.txt | awk -F " " ‘{sum+=$2} END{print sum}’
150
问题1:Shell脚本里如何检查一个a.txt文件是否存在?如果不存在则创建,并写入aaa?
#!/bin/bash
if [ -f a.txt ]; then
echo “文件存在!”
else
echo “文件不存在!”
echo “aaa” >> a.txt
问题1:用shell写一个脚本,对文本中无序的一列数字排序
[jinghnag@hadoop101 ~]$ cat test.txt
9
8
7
6
5
4
3
2
10
1
[jinghnag@hadoop101 ~]$ sort -n test.txt|awk '{a+=$0;print KaTeX parse error: Expected 'EOF', got '}' at position 2: 0}̲END{print "SUM=… sort -n test.txt | awk 'BEGAIN{a=0}{a+=$0;print KaTeX parse error: Expected 'EOF', got '}' at position 2: 0}̲END{print "SUM=… grep -r “shen” /home | cut -d “:” -f 1
/home/jinghnag/datas/sed.txt
/home/jinghnag/datas/cut.txt