shell技巧

1. Shell对数组的支持

ksh脚本中数组定义:set –A  ArrayName first second third

则:

ArrayName[*]=first second third

ArrayName[0]=first

ArrayName[1]= second

ArrayName[2]= third

${# ArrayName[*]}=3  -------------输出:数组长度3

Shell数组中没有地址和引用的概念,不能通过数组名传递数组内容:

tmpName= $ArrayName

echo $tmpName        -------------输出:first

shell数组不支持整体赋值:

tmpName= ${ArrayName[*]}

echo $tmpName        -------------输出:first second third

echo ${tmpName[0]}    -------------输出:null

bash脚本不支持数组;csh脚本支持数组格式:Set x=(a b c)

2. shell脚本中命令执行格式

下面这几个计算表达式都是可以的:

k=`expr $i \* 2`

k=$( expr $i \* 2  )

k=$((i*2))

------k值计算结果相同。

下面两个操作得到的结果也是相同的:

str="ls -al"

$str

str=" ls -al | grep “ostool”"

$str

 

 

 

通过字符串执行command时,只能执行一个命令,不能使用“|”管道操作连接多个命令。

shell中用${cmd变量}执行变量内容,但该类操作仅仅支持一个命令,不支持嵌套或连接多个命令。

cmd="echo y && echo x"

${cmd}    -----输出y && echo x

cmd="echo 'y'"

${cmd}  ---------------输出'y'

3. 文件测试的返回值

[ -f tmpfile]       或者         test -f tmpfile

echo $?             ----------返回值为0,表示文件可读;非零,表示文件不存在。

另一方面,

if [ -f tmpfile ]

then

        echo "1"

else

        echo "0"

fi

文件tmpfile存在时,输出1;文件tmpfile不存在时,输出0

这样理解,if []语句中判断的是“-f”操作结果;$?表示“[]”操作的结果。

4. shell执行命令:

cmd是没有执行完成,下面语句输出结果不同。

cmd | grep “1233”         --没有任何输出

cmd > filename           --没有任何输出

cmd                    --输出cmd执行中间过程的输出

前两种shell语句在cmd执行结束前,不会输出任何结果;第三种语句可以实时输出结果到标准输出。因此,如果cmd是一个循环、或者需要用户输入,那么前两种语句不会结束了。

这样的shell语句,如果cmdxxx需要读取用户输入,用户输入时

cmdxxx | tee -ia logfile

echo “procedue over!”

问题:shell脚本里调用cmdfunc后,被调过程的输入输出与调用过程输入输出是什么关系?系统IO缓冲区是给谁占用的?

exec cmd          ----践踏了调用这的shell环境变量

cmd              ----启动新shell执行cmd,父子两个shell会共用IO缓冲区

5. shell中trap命令的使用

trap为系统中一些特殊消息指定处理接口,如ctrl+c对应的是2号消息:

脚本执行 trap “trap_proc” 2  后,

脚本运行过程中 ctrl+c键时系统运行trap_proc过程,直到函数结束,函数trap_proc结束后,trap会复原为系统默认操作。

6. shell脚本中访问变量必须防止空变量报错

脚本中必须使用双引号将变量引起来,因为如果变量为空,可能导致脚本执行出错。如:

[ -z  ${var1} ] && continue   ---------var1为空,该表达式会出错。

如果是参数变量,则必须将整个表达式用引号括起来:

[ -z  “$1” ] && continue

7.  模式匹配表达式中使用变量值

Shell脚本中读取变量值只能用“${myvar}”,在模式匹配表达式中“$”是元字符,“\$”只表示字符,因此在模式匹配表达式中读取变量值的方法只能如下:

sed -n '/ '${proc_name}'/=' tmpfile           -----打印包含“${proc_name}”的行号

将所有字符串直接拼在一起,将“${proc_name}”置于单引号外,sed可以正常执行该命令。

8.  10进制、16进制相互转化

16进制数字转化成10进制数字:

    parm=$1

    if echo $parm | grep -q "^ *0[xX]"

    then

bc << @@

        ibase = 16                        ##输入为16进制

        ${parm#0[xX]}

@@

        return

    fi

bc命令默认处理的是10进制数字,${parm}已经是10进制了。

另外:

${parm}  --------内容是”0x1a”

${parm#0x}  --------内容便是”1a”

9.  Shell读取用户输入,如何判断数字还是字符

方法:

read user_input

`expr $user_input + 0` >/dev/null 2>&1

if [ $? -eq 0 ]

then

    用户输入了非零数字

fi

用数字运算的命令返回值来验证输入是否为非零数字,当输入0时,expr表达式返回1。验证表明:expr表达式计算结果为0时,命令返回值就是1

10. grep/sed/awk

Grep选项:

-i:不区分大小些;

-c:显示匹配行数;

-n:显示匹配行号、行内容;

-v:显示不匹配行内容;

‘’:单引号支持正则表达式;

-r:搜索指定目录。

 

Sed选项:

-n:默认不输出;

‘/RegularExpression/p’:打印输出编辑行内容;

‘/RegularExp/d’:删除匹配行;

‘/ RegularExpression /=’:打印行号;

‘/RegularExpression/’:正则表达式使用;

‘1,20s/string1/string2/’1-20行进行字符串替换;

‘4,$p’    :打印4以后行内容;

\dnn(十进制),\onn(八进制),\xnn(十六进制)分别表示字符;

Sed是面向行的编辑工具,操作分两步:确定行地址,执行操作。

 

Awk选项:

Awk [–Ffield_seprator] ‘/RegExp/ {action}’ Infile

awk '/sun/{print}' mydoc       ---打印匹配的行;

awk -F % 'NR==7,NR==15 {printf $3}' ---显示文本文件myfile中第七行到第十五行中以字符%分隔的第三字段;

11. test用法

test 条件测试,语法  test  [选项参数

                 选项  -f 文件  若文件存在且可读则真

                          -w  文件若文件存在且可写则真

                          -x文件若文件存在且可执行则真

                          -f文件若文件存在且为普通文件则真

                          -d文件若文件存在且为目录文件则真

                          -p文件若文件存在且为fifo文件则真

                          -s文件若文件存在且不空则真

                          -z串若串长度为0则真

                          -n串若串长度不为0则真

                                 若串不是空串则真

                         1=2若串1等于串2则真

                         1!=2若串1不等于串2则真

                          n1 -eq n2n1n2数值相当则真

                          n1 -ne n2n1n2数值不相当则真

                          n1 -lt n2n1小于n2则真

                          n1  -le  n2   n1小于等于n2则真

                          n1  -gt  n2        n1大于n2则真

                          n1  -ge  n2        n1大于等于n2则真

         可用 与 -a 或 -o 非 ! 将条件表达式连接起来

12. 删除文件中重复行

方法1sort file1|uniq>file2

-----sort默认按升序排序,uniq删除重复行;

方法2awk '!($0 in a) {a[$0]; print $0}' filename

-----若记录$0不在a数组,则加入到数组且打印该记录。

13. 删除DOS格式的回车符

方法1:dos2unix 转化格式,vi另存为unix格式。

方法2sed –e ‘s/.$//’ mydos.txt > myunix.txt

-----sed命令中字符串替换命令,将结尾符(换行)前的任意字符替换为空。

方法3cat mydos.txt | tr –d ‘\r’ >myunix.txt

------tr命令删除delete回车符,仅保留换行符’\n’

 

14. 逐一执行目录下的文件

for file in `ls $HOME/XXXX/*.tcl 2>/dev/null`

do

    $file >>/dev/null

done

 

15. 逐行处理文件内的语句

while read inputline

do

    process_lines $inputline

done < ./XXXX

 

 

你可能感兴趣的:(shell技巧)