分类:
2009-12-07 22:57:49
==================================================
AWK学习笔记:
==================================================
1、匹配第4列包含"Brown"的行
awk '{if($4~/Brown/) print $0}' grade.dat
2、匹配第1列包含 Brown 或 Yellow的 行
awk '{if($1 ~ /Brown/ || $1 ~ /Yellow/) print $0}' grade.dat
3、匹配第3列等于"48"的行
awk '$3!="48"{print $0}' grade.dat
4、内置变量的用法:
3.1、NR: 已读的记录数: awk '{print $0}END{print NR}' grade.dat
3.2、NF: 浏览记录的域个数: awk '{print NF" "NR" "$0}END{print FILENAME" has counts: "NF}' grade.dat
NF还有一个强大的功能是将变量$pwd的值传入awk并显示其目录,如:echo "bossapp/lele/into" | awk -F/ '{print $0}'
5、awk操作符
设置域变量名: awk '{name=$1;belts=$4; if(belts ~ /Yellow/) print name " is belt "belts}' grade.dat
awk 'BEGIN{scolor="Yellow"}{name=$1;belts=$4; if(belts == scolor) print name " is belt "belts}' grade.dat
修改域的值:awk '{if($4 ~ /Brown/) {$4="new Brown";$6 -= 1};print $0}' grade.dat
创建新的域:awk 'BEGIN{newfield=0}{newfield=$6+$7; print $0 "\t" newfield; OFS="----"}' grade.dat
求某列值总和: awk '{total += $6;}END{print "Club student total points : "total}' grade.dat
打印某个目录下所有文件名及其大小:
ls -l | awk ' /^[^d]/ {print $8"\t"$5; total += $5} END{print "all files size is : " total}'
6、awk内置字符串函数
gsub(s,t): awk ' gsub(/48311/, a) {print $0}' grade.dat
index(s,t): awk '{print index($1,"M.")}' grade.dat
length(s): awk '{print length($3)}' grade.dat
match(str,reg): awk '{print match($1,/^J/)}' grade.dat
split(str,arr,fx): awk '{split("a/b/c/d", arr, "/"); print arr[1]}' grade.dat
sub(reg, str): awk '{str="poped popo kell"; sub(/op/, "OP", str); print str}' grade.dat
substr(str, i, len): awk 'BEGIN{str="poped popo kell"}END{print substr(str, 1, 5)}' grade.dat
$str = "poped popo kell"
echo $str | awk '{print substr($0,1,7)}'
7、awk的printf函数
echo "11" | awk '{printf "%x\n",$0}'
awk '{printf "%-15s %s\n",$1,$2}' grade.dat
awk '{AGE = 29; if($7 < AGE) print $0}' grade.dat
df | awk '{print $3}'
==================================================
sed学习笔记:
==================================================
1、匹配指定行
sed -n '2p' quote.dat
2、匹配指定范围的行
sed -n '1,3p' quote.dat
3、匹配包含某单词的行
sed -n '/honeysuckle/p' quote.dat
4、匹配以ing结尾的某单词的行
sed -n '/.*ing/p' quote.dat
sed -n '/.*ing/=' -e '/.*ing/p' quote.dat
5、替换文本
sed 's/night/NIGHT/' quote.dat 只替换第一次出现的night
sed 's/night/NIGHT/g' quote.dat 替换全局所有的night
sed 's/night/NIGHT/w sed.out' quote.dat 将修改结果输出到文件sed.out
6、插入
sed -n 's/night/light &/p' quote.dat 在night前插入light
sed 's/The/& addword/' quote.dat 在The后插入addword
7、将sed结果写入文件
sed '1,2 w sed.out' quote.dat 将quote.dat的第1、2行写入到sed.out文件中
8、在指定行的下一行,附加另外一个文件的内容
sed '/night/r sed.out' quote.dat
9、首次匹配到某单词后退出
sed '/music/q' quote.dat
sed 's/^M//q' quote.dat
9、例:去掉路径前的/ , 在最后加一个/
echo $PWD | sed 's/\///' | awk -F/ '{print $0"\/"}'
小结:sed 命令主要用于文本过滤及处理
==================================================
sort、uniq学习笔记
==================================================
sort:
1、按逆序排序
sort -r vid.dat
2、按指定域排序
sort -t: +1 vid.dat
3、对于数值列排序
sort -t: +2 vid.dat 先按第一个数字进行排列,再按第二个数字排列,依此类推。和字符排列一样
sort -t: +2n vid.dat 按数值大小排序
4、从某域的第n个字符开始排序
sort -t: +2.2n vid.dat
5、指定域从1开始计数
sort -t: -k1 vid.dat
6、删除重复的行
sort -u +5 vid.dat
uniq:
7、只显示不重复行
uniq -u a1.c
8、只显示重复的一行
uniq -d a1.c
9、显示复重的行数
uniq -c a1.c
10、只按某个域进行重复排序
uniq -f2 ab.c
join:
11、连接join
join ab.c abc.c
12、左连接
join -a1 ab.c abc.c
13、右连接
join -a2 ab.c abc.c
14、显示指定的域
join -o 1.1,1.2,2.1,2.2 ab.c abc.c
15、指定匹配域连接
join -j1 1 -j2 1 ab.c abc.c
cut:
16、以":"为分隔符,剪切域1
cut -d: -f1 vid.dat
17、以":"为分隔符,剪切域1、3
cut -d: -f1,3 vid.dat
18、以":"为分隔符,剪切域1至3
cut -d: -f1-3 vid.dat
19、以空格为分隔符,剪切域1
cut -d" " -f1 grade.dat
paste:
20、粘贴两个域,以@为分隔符
paste -d@ ab.c abc.c
21、把列变成行来粘贴
paste -s ab.c abc.c
22、管道输入,"-"接受变量输入
ls | paste a1.c -
split:
23、默认按1000行分割,保存为x[aa]--x[zz]
split grade.dat
24、指定行数进行分割
split -2 grade.dat
==================================================
tr学习笔记
==================================================
1、消除重复的字符串序列
tr -s "[a-z]" < oo.dat : 消除重复的小写字母
tr -s "[0-9]" < oo.dat : 消除重复的数字
2、删除空行
tr -s "[\n]" < oo.dat
3、从大字转换成小写
tr "[A-Z]" "[a-z]" < oo.dat
4、删除末行的控制字符 "^M"
tr -s "[\r]" "[\n]" < data.f | cat -v
小结:常用于删除空行,大小字替换,删除控制字符
==================================================Shell变量学习笔记
==================================================1、若变量定义,则使用默认值
echo ${variable-name:-defaultValue}
2、若变量定义,则输出错误信息
echo ${variable-name:?} 输出系统错误信息
echo ${variable-name:?"my error message"} 输出自定义错误信息
3、将变量设置成只读
readonly variable-name
4、查看所有系统变量
env
5、系统变量必须用export命令导出
6、设置传入变量
$0为脚本名
$1 为第1个参数
例如:
脚本myScript
find . -name $1 -print
调用:myScript myparam
其中myparam当作参数($1)传给脚本中的find命令
7、一些特定参数变量
$? : 显示最后一个命令退出状态,0为成功,其他值表明的错误
$# : 传递到脚本的参数的个数
$$ : 显示脚本运行的当前进程ID号
$* : 以一个字符串显示所有参数
$@ : 在引号中返回各个参数
==================================================条件测试 test 学习笔记
==================================================1、文件测试
有如下参数
-r : 可读
-w : 可写
-x :可执行
-d :目录
-f :正规文件
-u :文件有suid设置
例:
test -x wow
[ -x wow ]
可以将两个测试结果进行与或操作
-a : 与 [ -w wow -a -w wow ]
-o :或 [ -w wow -o -w wow ]
2、字符串测试
有五种格式
test "string"
test operator "string"
test "string" operator "string"
[ operator "string" ]
[ "string" operator "string" ]
其中,operator可以为:
= :两个字符串相等
!= :两个字符串不等
-z : 空串
-n : 非空串
3、数值测试
格式:
test "number1" operator "number2"
[ "number1" operator "number2" ]
其中,operator可以为:
-eq :两数相等
-ne :两数不相等
-gt :>
-lt :<
-ge :>=
-le :<=
4、expr的用法
4.1 expr用于数值计算
如:expr 1 + 2
expr 5 \* 3
expr 5 / 3 : 结果为1,不保留小数位
4.2 用例:用于循环计数
loop=0
loop=`expr $loop + 1`
4.3 expr用于字符串
expr "a" = "a" : 特别需要注意的是,如果成功返回1,返回其它值为错误
4.4 expr用于模式匹配
value="accounts.doc"
expr $value : ".*" 统计任意字符出现的次数,也就说统计单词的个数
expr $value : ".c" 统计c出现的
==================================================控制结构(while、for、until loop、if then else)
==================================================一、if then else 结构
格式: if 条件1; then
语句1;
elif 条件2; then
语句2;
fi
例1:名字为空,则输出信息
#!/bin/sh
echo -n "Please Enter your name:";
read NAME;
if [ "$NAME" = "" ]; then
echo "you havn't Enter your name!";
fi
例2、用户输入名字列表,脚本判断是否包含peter
#!/bin/sh
echo -n "Please Enter your name:";
read NAMELIST
if echo $NAMELIST | grep "peter" > inle/null 2>&1
then
echo "peter is here";
else
echo "peter is not here";
fi
例3、文件复制输出检查。自定义错误信息
#!/bin/sh
if cp wow wow_copy >>inle/null 2>&1
then
echo "复制成功!";
rm wow_copy;
else
echo "脚本`basename $0`发生错误,原因为: cp命令发生错误";
fi
例4、当前目录测试
#!/bin/sh
DIRNOW=`pwd`
if [ "$DIRNOW" != "/" ]
then
echo "your are not at the dir of / " >&2
exit 1
fi
例5、测试传递到脚本的参数
#!/bin/sh
if [ $# != 3 ]
then
echo "`basename $0`的参数个数不正确!应该为3个" >&2
exit 1
fi
echo "arg1: $1"
echo "arg2: $2"
echo "arg3: $3"
例6、登陆测试脚本,用户名和密码必须是peter/hellen--123
#!/bin/sh
#设置登陆标志
INVAIL_USER=yes
INVAIL_PWD=yes
#保存当前stty设置
SAVESTTY=`stty -g`
echo "welcome to XX System for unix, now you will login to the system"
echo "please Enter your username:"
read USERNAME
#设置输入密码时不可见
stty -echo
echo "please Enter your password:"
read USERPWD
#恢复之前stty设置
stty echo
if [ "$USERNAME" = "peter" -o "$USERNAME" = "hellen" ]
then
INVAIL_USER=no
fi
if [ "$USERPWD" = "123" ]
then
INVAIL_PWD=no
fi
if [ "$INVAIL_USER" = "no" -a "$INVAIL_PWD" = "no" ]
then
echo "now you have login into System"
else
echo "username or password is invaild, please check them and login next time"
exit 1
fi
二、case
例7、一个简单的case例子,其中配置部份可以用"|"来作为或命令
#!/bin/sh
echo "please Enter your choose:"
read ANS
case $ANS in
1) echo "you have selected 1"
;;
2) echo "you have selected 2"
;;
3) echo "you have selected 3"
;;
4) echo "you have selected 4"
;;
5) echo "you have selected 5"
;;
*) echo "`basename $0`发生错误: the choose is not between 1 and 5" >&2
esac
三、for
格式:
for 变量 in 列表
do
程序体
done
其中,列表可以是Shell命令
例8、一个最简单的for循环
#!/bin/sh
for loop in 1 2 3 4 5
do
echo $loop
done
例9、将ls的结果打印出来
#!/bin/sh
for loop in `ls`
do
echo $loop
done
例10、将参数打印出来
#!/bin/sh
for loop in $*
do
echo $loop
done
例11、在for程序体中使用find,实现多文件查找
for loop
do
find . -name $loop -print
done
例12、统计当前目录下的文件数目
#!/bin/sh
count=0
for loop in *
do
count=`expr $count + 1`
done
echo "there is $count files"
其实用ls | wc -l 也能统计出当前目录下文件的个数
四、until
例13、查看root用户是否登陆,登陆则给其发个邮件
#!/bin/sh
IS_ROOT=`who | grep root`
until [ "$IS_ROOT" ]
do
sleep 5
echo "no login"
done
五、while
例14、输出1-10
#!/bin/sh
i=0
while [ $i -lt 10 ]
do
echo $i
i=`expr $i + 1`
done
例15、从键盘读字符串,按ctrl+D结束读入
#!/bin/sh
echo -n "Enter: "
while read name
do
echo "output: $name"
done
例16、用while循环读取文件的每一行
#!/bin/sh
while read FLINE
do
echo $FLINE
done < data.f
例17、以:为分隔符,依次读取域信息
#!/bin/sh
SAVEIFS=$IFS
IFS=:
while read NAME DEPT
do
echo "$NAME\t $DEPT\t"
done < name.txt
IFS=$SAVEIFS
例18、默认以空格为域分隔符
#!/bin/sh
while read f
do
echo "$f1-----------$f2"
done < name.txt
说明下:无论是以什么作为分隔符,read后面的变量个数要与域的个数相同,这样就可以用变量一一对应域了
例19、每回读两行
#!/bin/sh
while read rline1
do
read rline2
echo $rline1
echo $rline2
echo "--------------------------"
done < name.txt
例20、while循环和文件描述符 做文件备份,按行读取,写到另一个文件
#!/bin/sh
FNAME=wow
FNAME_BAK=wow.bak
if [ -s $FNAME ]; then
#将wow描述为输入文件
exec 3<$FNAME
#将wow描述为输出文件
exec 4>$FNAME_BAK
while :
do
read LINE
if [ "$?" != "0" ]; then
#关闭输入和输出
exec 3<&-
exec 4<&-
exit 0
fi
echo $LINE >&4
done <&3
else
echo "文件不存在!"
fi
六、break、continue
break 2 可以跳出两重循环
例21、用break(continue)跳出两重循环
#!/bin/sh
while :
do
echo "这是第一重循环"
while :
do
echo "这是第二重循环"
break 2
done
done
==================================================自定义函数
==================================================1、定位文件: . 文件名
这样就可以把文件中包含的函数当成系统函数了,直接调用即可,但只能在本终端运行,离开本终端就不行了
例22、自定义查找函数,可查找多个文件
#!/bin/sh
myfind() {
if [ $# -lt 1 ]; then
echo "至少有一个参数"
return 1
fi
for loop in "$@"
do
find . -name $loop -print
done
}
例23、检查名字是否全是英文
#!/bin/sh
#定义检查函数
check_name() {
_PARAM_NAME=$1
_PARAM_NAME=`echo $1 | awk '{if($0 ~ /^[a-zA-Z]+$/) print "1"}'`
if [ "$_PARAM_NAME" != "" ]; then
return 0
else
return 1
fi
}
#定义错误提示函数
name_error() {
echo "$@ 包含非法字符,请确保全部是英文字母"
}
#开始调用
while :
do
echo "请输入你的姓氏:"
read FIRST_NAME
if check_name $FIRST_NAME; then
break
else
name_error $FIRST_NAME
fi
done
while :
do
echo "请输入你的名字:"
read SEC_NAME
if check_name $SEC_NAME; then
break
else
name_error $SEC_NAME
fi
done
echo "你的名字为:$FIRST_NAME $SEC_NAME"
==================================================向脚本传递参数
==================================================一、shift的作用:指向参数的位置偏移一位,从1开始
例24、用shift实现参数位置偏移
#!/bin/sh
while [ $# -ne 0 ]
do
echo $1
shift
done
例25、自定义大小写转换命令
#!/bin/sh
#文件内容的大小写转换命令
FNAME=""
OPT="no"
CASEOPT=""
#自定义错误函数
error_msg() {
echo "`basename $0`: Error the conversion faild, please enter `basename $0` -help" >&2
exit 1
}
#大小写转换
l_u_case() {
for
do
case $CASEOPT in
lower)cat $LOOP | tr "[a-z]" "[A-Z]" >>l_rslt.dat
;;
upper)cat $LOOP | tr "[a-z]" "[A-Z]" >>u_rslt.dat
;;
esac
done
}
#若不输入参数,则报错
if [ $# -eq 0 ]
then
error_msg
fi
#循环遍历参数,进行处理
while [ $# -gt 0 ]
do
case $
-l)OPT="yes"
CASEOPT="lower"
shift
;;
-u)OPT="yes"
CASEOPT="upper"
shift
;;
-help)echo "this is help"
exit 0
;;
-*) error_msg
;;
*) FNAME=$1
OPT="no"
shift
;;
esac
done
#下面开始处理文件
if [ $OPT = "no" ]
then
if [ -f $FNAME ]
then
l_u_case
exit 0
else
echo "$FNAME is not a file ,please check it"
exit 1
fi
else
exit 0
fi
二、getopts: 获取用"-"开始的参数,如-fu, 其作用与-f -u 是一样的
例26、
#!/bin/sh
while getopts :afu: OPTS
do
case $OPTS in
a)echo "ALL"
;;
f)echo "FULL"
;;
u)echo "USER"
;;
\?)echo "error" >&2
exit 1
;;
esac
done
例27、-u选项必须带值,否则报错(若要屏蔽系统错误,在前面加:即可); 带入的值用变量OPTARG接收
#!/bin/sh
while getopts :afu: OPTS
do
case $OPTS in
a)echo "ALL"
;;
f)echo "FULL"
;;
u)echo "USER--$OPTARG"
;;
\?)echo "error"
exit 1
;;
esac
done
==================================================一些比较杂的东西
==================================================一、信号:系统向脚本发出的信息或命令,有如下含义:
信号 信 号 名 含 义
1 SIGHUP 挂起或父进程被杀死
2 SIGINT 来自键盘的中断信号,通常是ctrl + c
3 SIGQUIT 从键盘退出
9 SIGKILL 无条件中止
11 SIGSEGV 段(内存冲突)
15 SIGTERM 软件中止,默认的
二、捕捉信号
trap
例28、当按下键盘中止后,用trap捕捉到信号,进行处理
#!/bin/sh
trap "tp_cmd" 2
tp_cmd() {
echo "hahahaha"
exit 1
}
loop=0
while :
do
loop=`expr $loop + 1`
echo $loop
sleep 1
done
例29、在某一段关键处理过程,可以屏蔽信号,从而保证完整性
#!/bin/sh
#设置屏蔽信号
trap "echo you can't interrupt me" 1 2 3 15
###这一段我是不希望被打断的,否则后果很严重噢,除非你用kill -9 begin
loop=0
while :
do
loop=`expr $loop + 1`
echo $loop
if [ "$loop" -eq "6" ]
then
break
fi
sleep 1
done
###这一段我是不希望被打断的,否则后果很严重噢,除非你用kill -9 end
#自定义退出函数
myexit() {
echo "hahahaha"
exit 1
}
##现在可以打断了,没关系
trap "myexit" 1 2 3 15
while :
do
loop=`expr $loop + 1`
echo $loop
sleep 1
done
三、eval
例30、自动生成变量
#!/bin/sh
loop=0
name="a"
while :
do
loop=`expr $loop + 1`
eval `echo "$name$loop=$loop"`
echo $name$loop=$loop
if [ "$loop" -eq "6" ]
then
exit 0
fi
done
四、别名alias
格式:alias 短命令='原命令'
用户文件夹下的.profile加入alias,就可以使短命令成为自定义命令了
别外,还可以写自定义函数,在.profile用 . 脚本名 装入内存,实现自定义命令