目录
常见错误
数组和字符串
基本语法-括号
循环,判断和分支
子函数
正则
文件读写
面试题
正文:
1 常见错误
1) 定义变量不能有空格
colon =`grep ":" "$result1"` # 注意colon后面的空格算成单词.
colon=`grep ":" "$result1"`
2) 中括号两遍必须有空格
if [ "$colon" -eq "0" ]
如果是||比较是 if [ "$colon" -eq "0" ] || [ "$linenum" -eq "1" ]
不是 if [ "$colon" -eq "0" || "$linenum" -eq "1" ]
3) 数值计算
i++
((i=i+1))
4) eval使用
所以此时我们需要通过使用eval来解决该问题,eval添加到语句的开头,在执行该语句的时候,会扫描两次该语句:第一次扫描能够替换变量对应的值,第二次扫描就是为了识别语句并运行该语句.
例子:awk的结果传给shell
string:ACCESS=Access
abce=`echo $result1 |awk -F '=' '{printf("gs=\"%s\";a=\"%s\"",$1,$2)}'`
eval $abce
echo "line39:$gs;$a;result1=$result1"
3 传参解析(同perl):$#参数个数,$@所有参数,参数$1,...
while getopts "a:b:cdef" opt; do
case $opt in
a) echo "this is -a the arg is ! $OPTARG";;
b) echo "this is -b the arg is ! $OPTARG";;
.......
4 数组和字符串
4.1 数值,string 比较
4.2 数组取值
for ((i=0;i<${#arr[@]};i++))
do
name=`echo ${arr[$i]} |awk -F '=' '{print $1}'`
gs=$gs";"$name
echo "line22:${arr[$i]};$name;$gs"
done
不是$arr[i]
eval ehco \$$# $#是数组最后的
arr=$_str string 转array.$#arr 即数组长
${#file} string length
4.3 数组和字符串转换
#!/bin/ksh
set -A a
b="1 3 5 7 9"
a=($b) //这是string 转成数组在ksh93
ksh88必须这样的才行,在string 转成数组的时候
b="1 3 5 7 9"
set -A a $b
------
echo ${array[@]}//print 整个数组
Array[3] = "a b c"
echo $Array[1] 输出b,
str=“a b c”
Array = ($str)
echo$Array[1],同样输出b,
要注意: Array = ($str)中的右值的括号不能缺
上面这个就是我们常说的把字符串放到一个数组中,也可以理解为动态数组,比C和C++简单多了
数组常见错误
typeset -i i=0
cnt=2
for ($i=0; $i<$cnt;$i++) {
echo "123"
}
temp.sh[4]: syntax error at line 4 : `(' unexpected
shell没有for()这种用法。
while ((i<cnt))
do
echo "123"
((i=i+1))
done
这是ksh93之后的语法
之前的话,(())用expr代替。
5 基本语法
循环,判断和分支
for file in *.c;do echo $file;gcc -o$(basename $file.c)$file ;sleep 2;done>compile 2>&1
break;continue
6 括号:大括号,小括号,中括号
(1) 小括号
1) 用于初始化数组。如:array=(a b c d)
2) $()等于``执行命令
3) (())表示计算在ksh93.
(2) 中括号
1) []表示test 。执行
[ expreession ] 执行。
[ "$A" = 123 ] string test
["$A" -eq 123] integer
[-e "$A" ] file
[ -n string ] string is > 0 is true
2) []数组下标
3) [[]] 支持模式匹配比较[[ hello == hell? ]] .多个判断 [[ &&/||>||< ]]
(3) 大括号
1)这时应该用变量的原形:${var},即是加一个大括号来限定变量名称的范围,如下 $ echo ${var}AA
2) 模式识别${}
${string%substring}
从$string的结尾位置截掉最短匹配的$
3) 子函数的代码段
abc ()
{
}
4) string 长度
${varible:n1:n2}:截取变量varible从n1到n2之间的字符串。
$ EXCLAIM=cowabunga
$ echo ${EXCLAIM:3:7} abunga
6 重定向 &1,&2
ls a 1 >file 2>&1 ; ls file 2>file >&2 ;>/dev/null 2>&1
exec 2 >file ;set -x; set +x
7 正则表达式
awk正则,string length($0),substr, -F, print $1 提取列
模式识别*
${varible##*string} --- 从左向右截取最后一个string后的字符串
${varible#*string} --- 从左向右截取第一个string后的字符串
${varible%%string*} --- 从右向左截取最后一个string后的字符串
${varible%string*} --- 从右向左截取第一个string后的字符串
“*”只是一个通配符可以不要
8 ret 和$?即输出和返回值的区别
ret=·find * -name "*.sh" -print
ret 表示output。$?表示执行是不是成功.
$? is 0;ret: extlab.sh
other:1) 转义字符 在"$a" 需要"\$a"
2) ``和$() 执行
3) 多条shell命令放到一起写。这些命令分开写也行。
set -A LAB_LIST $((cd /opt/cool/loaddata; ls *.par | sed 's/.par$//';egrep -v "^#|^$" ${TOOL_DIR}/data/ECPLenvironment |cut -d';' -f4) | sort -u)
一下批量执行几个shell
8 文件读写
1
while read line
do
echo "line=$line"
done<'ls -l /home/felixzh'
ls -l /home/felix/ |while read line
do
....
done
<后面跟的是文件名
|是管道
list=`ls -l $path`
然后<$list
ls -l $path不是文件,是一种输入stdout
没有文件名,不能叫文件.
2
shell 从file descriptor read data. 3是文件描述符
exec 3< $GUI2CMD_PIPE
while read -u3 data
do
echo $data
done
3
将文件的SRCCversionFile的内容,读入变量中
SRCCversionFile=$(cvp -r cool/NGNsrcc_lib/version 2>/dev/null)
SupportedVersion=$(< $SRCCversionFile)
使用"|"管道操作符, 将I/O流重定向到一个子shell中, 比如ls -al | (command).
其他参考
http://blog.csdn.net/xj178926426/article/details/6925770
第二部分 面试题
1 在目录/ tmp下找到100个以abc开头的文件,然后把这些文件的第一行保存到文件new中
-
#!/opt/exp/bin/perl -w
-
local *DH;
-
$cwd="/bld/felixzh/temp/shell/";
-
sub readline1 {
-
$file1=shift;
-
print "file1=$file1\n";
-
if (!open ($fd1,"<$file1")) {
-
warn "open file fail \n";
-
return undef;
-
}
-
$line1=<$fd1>;
-
# @lineall=<$fd1>;
-
# print "line1=$line1\n";
-
# print "lineall=@lineall\n";
-
writeline1($line1);
-
close($fd1);
-
}
-
sub writeline1 {
-
$line2=shift;
-
if (!open($fd2,">>$file2")) {
-
warn "open file fail\n";
-
}
-
print $fd2 "$line2";
-
close($fd2);
-
}
-
if (!opendir(DH,$cwd)) {
-
warn "cannot opendir $cwd:$! $^E";
-
return undef;
-
}
-
$file2=$cwd."line2.txt";
-
print "file2=$file2\n";
-
system "touch $file2";
-
foreach ( readdir(DH) ) {
-
if ($_ eq '.' || $_ eq '..') {
-
next;
-
}
-
my $file = $cwd.'/'.$_;
-
# print "$file \n";
-
if (/^s/) {
-
#read file line1
-
&readline1 ($file);
-
}
-
}
-
closedir(DH);
-
============================================
-
shell
-
path="/bld/felixzh/temp/shell"
-
str=`ls $path |egrep '(^s)'`
-
#change string to arry
-
set -A a ${str}
-
set -A b
-
#it only string assign to array's element
-
#a=$str
-
t=0
-
for item in $str
-
do
-
t=`expr t+1`
-
b[$t]=$item
-
done
-
echo "${b[@]}"
-
exit
-
#print all array
-
echo "${a[@]}"
-
#array length
-
cnt=${#a[@]}
-
echo "cnt=$cnt"
-
wfile="$path/line1.txt"
-
typeset -i i=0
-
while [ "$i" -lt "$cnt" ]
-
do
-
print "${a[$i]};i=$i\n"
-
line1=`cat ${a[$i]} |head -1`
-
echo "line1=$line1\n"
-
echo "$line1" >>$wfile
-
i=i+1
-
done
2 把文件b中有的,但是文件a中没有的所有行,保存为文件c,并统计c的行数
-
#!/opt/exp/bin/perl -w
-
$cwd="/bld/felixzh/temp/perl";
-
open ($fd1,"<$cwd/email1.txt");
-
open ($fd2,"<$cwd/email2.txt");
-
open ($fd3,">>$cwd/emaildiff.txt");
-
system (">$cwd/emaildiff.txt");
-
@a=<$fd1>;
-
@b=<$fd2>;
-
$i=0;
-
$a1=@a;
-
$b1=@b;
-
sub match {
-
$tline=shift;
-
$j=0;
-
while ($j<$b1) {
-
if ( "$tline" eq "$b[$j]" ) {
-
return 1;
-
}
-
$j++;
-
}
-
return 0;
-
}
-
while ( $i<$a1 ) {
-
$line1=$a[$i];
-
$result=&match($line1);
-
print $fd3 $line1."\n" if (!$result);
-
$i++;
-
}
-
system ("wc -l $cwd/emaildiff.txt");
-
======================
-
cwd="/bld/felixzh/temp/perl"
-
t1="$cwd/email1.txt"
-
t2="$cwd/email2.txt"
-
typeset -i i=0
-
typeset -i j=0
-
typeset -i k=0
-
typeset -i t=0
-
>"$cwd/emailsdif.txt"
-
while read line1
-
do
-
a[$i]=$line1
-
a[$i]="$line1\n"
-
# printf "${a[$i]}"
-
i=`expr $i+1`
-
done<$t1
-
k=$i
-
i=0
-
while read line2
-
do
-
b[$j]=$line2
-
b[$j]="$line2\n"
-
j=`expr $j+1`
-
done<$t2
-
t=$j
-
function match1
-
{
-
tline=$1
-
j=0
-
while [ "$j" -lt "$t" ]
-
do
-
if [ "$tline" == "${b[$j]}" ]
-
then
-
return 1
-
fi
-
j=`expr $j+1`
-
done
-
return 0
-
}
-
while [ "$i" -lt "$k" ]
-
do
-
line1=${a[$i]}
-
match1 "$line1"
-
if [ $? -eq 0 ]
-
then
-
echo $line1>>$cwd/emailsdif.txt
-
fi
-
i=`expr $i+1`
-
done
-
wc -l $cwd/emailsdif.txt