原文地址:http://erex.sinaapp.com/category/shell/
本文是在Fedora 13的环境下进行编写测试的,使用的是默认的shell,名字是GNU bash,版本号4.1.2。
告诉系统使用哪一个Shell
#!/bin/sh |
上面的代码告诉系统使用的Shell是位于bin目录里面的sh,实际上sh链接到bin目录下的bash文件,也就是说我们使用的Shell是bash。
注释一行代码
# comment |
C语言可以使用“//”来注释一行代码,在Shell编程中,符号“#”有同样的作用,以上代码中的comment不会被执行。
调用命令
rm -f "a.gif" |
和在控制台输入命令一样,直接输入代码即可。
变量的赋值
a=123 b="abc" c=3.14 |
Shell编程里面的变量不需要声明,直接赋值即可,支持整数和串两种类型。
变量的运算
a=3 b=4 c=$((a*b)) |
“$(())”能够实现简单的变量运算,只支持整数,在Shell编程中,浮点数只能作为串进行处理,不能直接进行运算。
数组
arr=(tiger sheep wolf) amimal=${arr[1]} arr[2]="monkey" |
以上数组定义了3个元素“tiger”“sheep”和“monkey”。通过“${}”符号可以取出数组的元素,数组的索引从0开始,所以第二行代码取出的值为“sheep”。第三行代码将修改数组的第三个元素为“monkey”。
逻辑判定
test -f "a.gif" [ -f "a.gif" ] |
以上代码都是判断a.gif这个文件是否存在,其中“[”看起来是个符号,实际上链接到“test”这个命令,其中的“-f”属于判断文件条件的参数,意思是判断这个文件是否存在。直接执行以上代码将看不到任何返回信息,因为逻辑判断需要和if或者while之类的语句联合使用。关于逻辑判定的参数有很多,比如比较大小的小于“-lt”、小于或等于“-le”等等,执行“man test”命令即可看到,这里不再累述。
if语句
bool=1 if [ $bool = 1 ]; then echo "Hello Shell!" else echo "This message won't show up." fi |
以上代码先给变量“bool”赋值为1,然后判断它是不是等于1,等于则显示“Hello Shell!”,否则显示“else”关键字后面的信息。这里由于已经确定“bool”是1,所以“else”关键字后面的输出不会显示出来。
while语句
n=7 i=0 while [ $i -lt $n ] do echo $i i=$((i+1)) done |
设定变量“n”为7,使用一个循环进行判断,当变量“i”小于“n”的时候循环继续,执行这段代码将输出0到7的整数。
文件读取与写入
tmp_file=./tmp.txt while read -r file_line do echo $file_line >> ./out.txt done < $tmp_file |
从“./tmp.txt”文件里面读取每一行放到“file_line”变量里面,然后输出追加到“./out.txt”这个文件。“>>”表示的是追加到文件末尾,“>”表示直接覆盖文件。
如果文件有n行,没一行固定有3个元素,那么可以用下面的代码来读取,这样,每行的3个元素都会分别自动存入到“a”“b”“c”3个变量。
while read -r a b c do echo $a $b $c done < $tmp_file |
替换变量中的字符串
str=xxxleftxxx str=${str/left/right} |
以上代码把变量“str”里面的子串“left”替换为“right”,不过只能替换第一个出现的串。“${}”符号在字串处理方面的用处还有很多,有兴趣可以自行查阅相关资料。
替换文件中的字符串
sed -i "s/left/right/g" ./a.txt |
这个将把“./a.txt”文件里面的所有“left”替换成“right”。
连接字符串
a=111 b=222 c=$a$b |
连接字符串简单的把变量写在一起即可,如果中间要加空格,可以用转义字符写成如下形式。
c=$a\ $b |
在文件中查找字串
grep "apple" "./news.txt" grep "apple" -A 3 -B 4 "./news.txt" |
第一行代码将在“./news.txt”文件中查找包含字串“apple”的行,并现实出来,第二行代码的区别在于它将同时显示出包含字串“apple”的行的前4行和后3行。grep的用法还有很多,可以使用man查看。
将返回输出保存到变量
str=`grep "apple" "./news.txt"` |
“./news.txt”文件中保存有字串“apple”的行将都被存入“str”变量里面,注意到,这个等号后面的命令是被符号“`”括起来的,这个符号在键盘“1”的左边,“Esc”的下面。
管道重定向
echo $vswr|awk '{printf("%lf", sqrt($1))}' |
“|”这个符号把前面的命令的输出作为后面命令的输入,这样可以简化中间的存取操作步骤。不过需要注意的是,由于重定向需要folk出新进程,所以在“|”之后的代码是无法修改之前代码中的变量的值的,如果需要修改,最好把输出存到一个临时文件,再作为后面命令的输入。
获取文件指定行
sed -n '4p' "./news.txt" |
获取文件的第4行。sed的用法还有很多,可以用man查看。
获取一行文本的指定列
a="aa bb cc" echo $a|awk '{print $1}' |
结果将输出第一列元素“aa”,由于“$0”将输出整个串,所以索引是从1开始的。
浮点数计算
pi=3.1415926 r=2 area=`awk 'BEGIN{printf("%lf", '$pi'*'$r'*'$r')}'` |
awk是个非常强大的命令,其中支持对C语言的模拟就为Shell编程增色不少。除了以上这种方法,还可以使用计算器bc进行计算。
area=`echo "$pi*$r*$r" | bc -l` |
关于浮点计算有些问题需要注意,由于在输入数据的时候只是简单的使用类似于C语言的宏替换,所以在减一个负数的时候回报错,类似于“–”这样连续两个减号是不允许的,所以最好用括号把变量括起来。另外bc不支持科学计数法,如果浮点数里面有E,它会报错。