Shell—学习之心得
由于项目要招聘需要有经验 shell 开发人员 (awk 编程 ) ,而作为技术面试官 ( 暂时 ) 的我对 shell 编程不太熟;当然以前也写过一些 shell 脚本来满足项目的需求 — 备份环境,数据库 ( 逻辑 ) 。假如只是针对 awk 编程的,那我绝对可以问倒他,呵呵 … 。所以我最近学习了 shell 编程。入门还不是很深,但是还是有点心得的。以下是本人的一些心得;大伙们觉得好,就拍个砖,不好也拿起你们的手鼓个掌 … 当然文中有什么错误 , 遗漏的也请指正我,大伙们对 shell 的总结也可以在下面回复。
1. shell之read命令
1.1 对 read 的参数 p,t,s,n 。在此我就不作什么描述了。但对参数 a 还是做下。 Read 也可以申明数组,例如 read01.sh
#!bin/
bash
#author li0924
read
-p
"
please entry your name:
"
-
a name
#执行在此输入多个字符串,以空格为分隔符
echo ${#name[@]};
#打印数组元素的个数
echo ${name[
0
]};
#打印第一个数组元素,注意数组是以下标为0开始
1.2 读文件;这个可能我们对read用到最多。每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出。读取文件的关键是如何将文本中的数据传送给read命令。最常用的方法是对文件使用cat命令并通过管道将结果直接传送给包含read命令的while命令。例如read02.sh
date文件:
View Code
#!/bin/
bash
count
=
1
while
read line
#cat 命令的输出作为read命令的输入,read读到的值放在line中
do
echo
"
$count:$line
"
count
=$(($count +
1
))
done
< date
#当然你可以在while前面加 “cat date |“来替换”<
date”
exit
0
1.3 大家有没有觉得这个效果跟awk ’{print FNR”:”$0}’ date一样。暂不作描述;本文重点不是awk。在上脚本;read后面只有变量line;其实可以跟很多变量。这个有点类似于awk中的$1-$9。例如read03.sh
#!/bin/
bash
cat date
|
while
read one two three #cat 命令的输出作为read命令的输入,read读到的值放在line中
do
echo
"
${one}:${two}:${three}
"
done
exit
0
拓展:Read命令用法我们知道了;最后留一个问题给大伙;该脚本中把three删除;打印$two是什么?添加four;打印$four有是什么?
2. 数组
2.1 数组的常规用法;数组的下标是从 0 开始的;这个在前面有提到!
A=
(a b c def)
# 定义$A数组
${A[@]} 或 ${A[
*
]}
可得到 a b c def (全部元素)
${A[
0
]}
可得到 a (第一个数组元素),${A[1
]} 则为第二个数组元素
${#A[
0
]}
可得到 1
(第一个数组元素(a)的长度),
${#A[
3
]}
可得到 3
(第四个数组(def)的长度)
A[
3
]=xyz
将第4个数组重新定义为 xyz
2.2 数组的长度
${#A[*]}或者${#A[@]}
2.3 删除数组 unset 数组 [ 下标 ] 可以清除相应的元素,不带下标,清除整个数据
unset A[
0
] #删除第一个元素
unset A #删除数组A
2.4 特殊使用 通过 ${ 数组名 [@ 或 *]: 起始位置 : 长度 } 切片原先数组,返回是字符串,中间用 “ 空格 ” 分开,因此如果加上 ”()” ,将得到切片数组, 例如下面测试
[li0924@localhost shell]$ A=
(a b c def)
#定义一个数组A
[li0924@localhost shell]$ echo ${A[@]:
0
:
3
}
#取前三个元素
a b c
[li0924@localhost shell]$ B
=(${A[@]:
0
:
3
})
#这个类似于B=
(a b c);其中括号里面是上述生产的
[li0924@localhost shell]$ echo ${B[@]}
a b c
[li0924@localhost shell]$ echo ${A[@]}
a b c def
讲到 ${ 数组名 [@ 或 *]: 起始位置 : 长度 } 是返回字符串;接下来我们学习字符串的处理
3. 字符串处理
其实shell语言不像其他编程语言对字符串处理的内置函数。这个也是我觉得shell很难学懂原因。慢慢发现shell主要功能不是针对文本处理,处理数据的。所以这部分自己理解就行了。我们定义一个变量file=/dir1/dir2/dir3/my.file.txt
3.1 求字符串长度
[li0924@localhost shell]$ echo ${#file}
27
[li0924@localhost shell]$ echo $file
| awk
'
{print length($0)}
'
#当然你也可以借用awk中的length函数
27
3.2 替换字符串
[li0924@localhost shell]$ echo ${file/dir/
path}
/path1/dir2/dir3/
my.file.txt
[li0924@localhost shell]$ echo ${file//dir/path}
/path1/path2/path3/my.file.txt
拓展: 当然你也可以用sed或者awk中的sub,gsub来实现。
[li0924@localhost shell]$ echo $file | sed
'
s/dir/path/
'
/path1/dir2/dir3/
my.file.txt
[li0924@localhost shell]$ echo $file
| sed
'
s/dir/path/g
'
/path1/path2/path3/my.file.txt
3.3 截取字符串 -- ${ 变量名 : 起始位置 : 长度 }
[li0924@localhost shell]$ echo ${file:
0
:
5
}
/
dir1
[li0924@localhost shell]$ echo ${file:
1
:
5
}
#下标是从0开始的;从0和1开始是有区别的;这个跟sql是不同。
dir1
/
[li0924@localhost shell]$ echo ${file:
-
4
}
#只提取最后4位.注意:跟-
4之间是有空格的;这个做个记号A
.txt
拓展:这里同样也可以用
awk
的
substr
函数实现。暂不演示。
4.
对未设定
,
空值的变量操作
Shell 对这些操作有很多,大伙可以自己去查看资料。我们暂时只讲 ${ 变量名 :- 默认值 } 。假如变量是为定义或者是空值就取默认值。有点类似于 sql 中的 nvl 函数。
[li0924@localhost shell]$ name=
lottu
#定义一个变量
[li0924@localhost shell]$ echo $name
lottu
[li0924@localhost shell]$ echo ${name:
-
li0924}
#name的值是lottu。所以结果是lottu
lottu
[li0924@localhost shell]$ unset name
[li0924@localhost shell]$ echo ${name:
-
li0924}
#name是未定义,所以取默认值li0924
li0924
拓展:对上述的记号A。去掉空格看下;无论file是否有值;效果都不是。
[li0924@localhost shell]$ echo $file
/dir1/dir2/dir3/
my.file.txt
[li0924@localhost shell]$ echo ${file:
-
4
}
/dir1/dir2/dir3/
my.file.txt
[li0924@localhost shell]$ unset file
[li0924@localhost shell]$ echo ${file:
-
4
}
4
5. shell中的三目表达式
5.1 我们的shell对三目表达式别具风格。语法是expr && cmd1 ||cmd2
[li0924@localhost shell] [
7
-gt
6
] && echo
"
0
"
||echo
"
1
"
5.2对数字运算也可以使用expr?cmd1:cmd2
[li0924@localhost shell]$ (( a =
7
>
6
?
0
:
1
))
[li0924@localhost shell]$ echo $a
0
6. 对冒号:和内置命令true
在某些条件判断,我们不需要做什么操作;但未了代码的完整性,我们可以在其中添加:或者 true 。这个类似其它语言的 null 。暂作简单测试。这里的:等价于 true 。
[li0924@localhost shell]$ [
7
-lt
6
] && : ||echo
"
1
"
1
[li0924@localhost shell]$ [
7
-gt
6
] && : ||echo
"
1
"
[li0924@localhost shell]$ echo $
?
0
[li0924@localhost shell]$ [
7
-gt
6
] &&
true
||echo
"
1
"
[li0924@localhost shell]$ echo $
?
0
最后奉送shell入门视频 http://www.cppcourse.com/shell-programming

