您的位置:首页 > 运维架构 > Shell

Linux之linux bash scripts

2015-09-20 23:12 501 查看
Linux之linux bash scripts

进程是程序运行时的内存空间和设置,存在于用户空间;用户空间是存放运行的程序和它们的数据的一部分内存空间。shell是用户和Linux内核之间的接口程序,围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。shell也是一个解释型的程序设计语言,支持绝大多数在高级语言中能见到的程序元素,如数据变量、参数传递、判断、流程控制、数据输入和输出,子程序及以中断处理等。
shell程序的编译过程分为预处理、编译、汇编、链接等几个阶段
大致的执行过程,图示:



1、执行指令,等待用户输入命令
2、将字符逐一读到寄存器中
3、再从寄存器取出放到主存中
4、键入命令结束后提交,代码和数据被拷贝到主存
5、执行主程序中的机器语言指令,并且从主存拷贝到寄存器堆
6、从寄存器中把执行过后的指令传到或者拷贝到显示设备
关于shell环境配置以及变量命名、作用、销毁等,已经在http://daisywei.blog.51cto.com/7837970/1690785博文做了简要的讲解。这里重点强调特殊变量
$0:当前脚本的文件名
$n:传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2
$#:传递给脚本或函数的参数个数
$*:传递给脚本或函数的所有参数
$@:传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到
$?:上个命令的退出状态,或函数的返回值
$$:当前Shell进程ID
程序基本格式:
行开始(必须方在文件的第一行):
#!/bin/bash 符号#!用来告诉系统它后面的参数是用来执行该文件的程序,被称为shebang。例子中我们使用/bin/bash来执行程序。当编辑好程序需要有执行权限(chmod +x filename)。
注:进行shell编程时,以#开头的句子表示注释,直到这一行的结束
bash脚本一般指文本文件。运行bash脚本指运行一个bash进程,此进程负责从脚本文件中读取一个执行逻辑,而后由bash进程负责解析并运行此逻辑
执行脚本命令有(注意要赋予执行脚本的文件有x执行权限):
1、 # bash /PATH/TO/SCRIPT_FILE
2、# ./PATH/TO/SCRIPT_FILE
bash命令常见选项:
bash -n bashname(脚本文件名) 检查bash脚本的语法错误
bash basename(脚本文件名) 执行脚本
bash -x bashname 显示脚本执行的详细过程

练习:
1、编辑test.sh并检查语法,显示详细的执行脚本过程(需要应用各个特殊参数表达的不同含义)




一般bash命令的执行状态结果,由bash追踪和保存,有:结果的返回值,状态返回值。
使用特殊变量$? :保存最近一条命令的状态结果
布尔型:真或假
bash命令状态返回值:成功:0;失败:1-255,(其中1、2、127被系统保留)
自定义脚本的状态结果:exit
(注:n必须是十进制数,范围必须是0-255,脚本中任何位置执行了exit命令即会终止当前shell进程)

练习:
1、查看执行状态



2、编辑test1.sh,打印执行返回状态





变量类型其他编程语言有多种类型,如C中定义变量需要声明整型、浮点型、字符型等。而shell脚本变量却是无类型的。shell不支持浮点型只支持整型(数值型)和字符型,同时字符型还具有一个整型值0(判断标准:变量中只包含数字是数值型其他是字符串)。
变量类型声明定义
declare –a name :表明数组array
declare –f name :表明函数function
declare –i name :定义整型变量
declare –r name :表示只读。不能使用unset
declare –x name :同export,在当前的环境中起作用,也在外部的shell环境中起作用,本地变量

test命令检查最后所执行命令的状态。test测试一个表达式,然后返回真或假。表达式一般是文本、数字或文件和目录属性的比较,并且可以包含变量、常量和运算符(字符串运算符、整数运算符、文件运算符或布尔运算符)
语法:test expression
[ expression ]
[[ EXPRESSION ]]
整数变量、字符串变量算术比较:
对应操作 整数操作 字符串操作
相等 -eq =
不等 -ne !=
大于 -gt >
小于 -lt <
大于或等于 -ge
小于或等于 -le
为空 -z
不为空 -n

判断文件属性的操作符:
-e file:判断文件是否存在,并返回真或假
-f file:文件是否存在且为普通文件
-s file:文件是否存在且大小不为0
-d file:文件是否存在且为一个目录
-h file:是否存在且为符号链接文件
-b file:是否存在且为块设备文件
-c file:是否存在且为字符设备文件
-S file:是否存在且为套接字文件
-p file: 是否存在且为管道文件

-r file:判断当前文件对当前用户可读
-w file:判断当前文件对当前用户可写
-x file:判断当前文件对当前用户可执行
-g file:判断当前文件对当前有SGID权限
-u file:判断当前文件对当前有SUID权限
-O file: 当前用户是否为指定文件的属主
-G file: 当前用户是否为指定文件的属组

双目操作符:
file1 -nt file2 文件1比文件2更新 (注意:这里指file1与file2最近一次的修改时间戳)
file1 -ot file2 文件1比文件2更老 (注意:这里指file1与file2最近一次的修改时间戳)

特殊设备:
/dev/null: 空设备,是一个特殊的设备文件,它丢弃一切写入其中的数据
/dev/zero:一个特殊的文件,读取它时,会提供无限的空字符(NULL, ASCII NUL, 0x00)

逻辑判断:
!:非,对指定的条件取反
-a:与,多个条件要同时满足
-o:或,多个条件满足其一即可
||:用or来合并两个条件(也称短路操作符)
&&:用and来合并两个条件(也称短路操作符)
短路操作符,逻辑判断真与假
false && true = false
false && false = false
true && false = fase
true && true = true
true || true = true
true || false = true
false || true = true
false || false = false
练习:
1、通过运行脚本test2.sh、test3.sh,对两个数值的比较









2、通过运行脚本test4.sh,对两个字符串的比较





3、判断目录$test是否存在,不存在,则创建





4、判断普通文件$test是否存在,不存在,则新建





5、判断$test是否存在并且具有执行权限,没有执行权限,并赋予执行权限



6、写一个脚本实现如下功能:获取当前主机的主机名;如果当前主机的主机名为空,或者为localhost,则将其修改为10.com



7、自动清空日志文件的内容(使用双目操作并且重定向、特殊设备)



read命令:从标准输入中读取一行
语法:read [ -p ][ -r ][ -s ][ -u[ n ] ] [ VariableName?Prompt ] [ VariableName ] ...
-p "内容":屏幕就会输出提示语句
-t 时间 :等待时间
练习:
1、输出提示语“enter your name:”,并且显示名字



命令引用,将直接引用执行结果:
`命令`:被反引号
$(命令)
注意:$[ 算术运算式 ]的形式进行求值,[]必须有空格分隔,只支持整型运算(常用的算术运算符+, -, *, /, %, **等)
$((运算式))的形式也可以进行算术运算求值,并且可以进行布尔运算
let 运算式也能进行算术运算,算术式各元素间不得有空格,否则应将算术式用引号括起来
练习:
1、显示当前时间(用两种方法引用)



2、计算5和6的和




bash之流程控制if/else(条件判断)、case语句
格式:单分支、双分支、多分支
if [ 条件判断式 ]; then
语句块 //当条件判断式为真时,执行该语句块
fi

if [ 条件判断式 ]; then
语句块 //当条件判断式为真时,执行该语句块
else
语句块 //当条件判断式为假时,执行该语句块
fi
case语句:重分支的应用场景,类似if语句多分支
格式如下:
case 变量名 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
*)
默认执行的命令序列
esac
注:case行尾必须为单词“in”,每一个模式必须以右括号“)”结束;双分号“;;”表示命令序列结束;匹配模式中可是使用方括号表示一个连续的范围,如[0-9];使用竖杠符号“|”表

示或;最后的“*)”表示默认模式,当使用前面的各种模式均无法匹配该变量时,将执行“*)”后的命令序列
练习:
1、写一个脚本if01.sh,判断当前文件系统为Linux,如果是则显示



2、写一个脚本if02.sh,判断当前系统为Linux或者FreeBSD、Solaris,如果以上都不是则显示是什么操作系统



3、写一个脚本if03.sh,完成如下功能;判断给定的两个数值,孰大孰小(给定数值的方法:脚本参数,命令交互)



4、写一个脚本case01.sh,由用户从键盘输入一个字符,并判断该字符是否为字母、数字或者其他字符,并输出相应的提示信息。



5、写一个脚本if04.sh可接受四个参数start: 创建文件/var/lock/subsys/SCRIPT_NAME、stop: 删除此文件、restart: 删除此文件并重新创建、status: 如果文件存在,显示为"running",否则,显示为"stopped"、basename命令:取得路径的基名 (使用case语句)
#!/bin/bash
#
prog=$(basename $0)                                                                 #获取路径的基名
lockfile="/var/lock/subsys/$prog"                                                   #定义lockfile变量并赋值
if [ $# -lt 1 ]; then                                                               #判断传递参数个数($#)小于1则显示下面echo内容,并退出
echo "Usage: $prog start|stop|restart|status"
exit 1
fi
case $1 in                                                                          #判断第一个参数
start)                                                                              #如果第一个参数为start则继续执行下面语句
if [ -f $lockfile ]; then                                                           #判断文件是否存在,存在则显示下面echo内容
echo "$prog is started yet."
else
touch $lockfile && echo "Starting $prog ok..." || echo "Starting $prog failed..."   #如果不是start参数则创建文件,并且显示文件内容,||注意这里的短路操作符
fi
;;
stop)                                                                               #判断为stop则继续执行下面语句
if [ -f $lockfile ]; then
rm -f $lockfile && echo "Stop $prog ok...." || echo "Stop $prog failed..."
else
echo "$prog is stopped yet."
fi
;;
restart)                                                                            #判断为restart
if [ -f $lockfile ]; then
rm -f $lockfile && touch $lockfile && echo "Restarting $porg ok..."
else
touch $lockfile && echo "$prog is stopped, Starting $prog ok...."
fi
;;
status)                                                                             #判断为status
if [ -f $lockfile ]; then
echo "Running..."
else
echo "Stopped..."
fi
;;
*)
echo "Usage: $prog start|stop|restart|sttus"                                       #如果用户输入的都不是以上的字符,则给出提示输入相关可使用的字符
exit 1
esac



bash之流程控制for、while、until(循环)
循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for、while和until。while循环和for循环属于“当型循环”,而until属于“直到型循环”。循环控制符:break和continue控制流程转向。
for循环:列表for循环(列表非空开始进入循环体,遍历列表循环结束),不带列表for循环
格式:
for 变量 in 列表[list];do ---列表list:是由一个或多个空格或换行符分隔开的字符串组成;把列表的每个字符串逐个赋值给变量
语句块
done

for 变量 ;do
语句块
done
列表list获得方法:
1、整数列表{start..end} $(seq [start [[step]] end)
2、直接给出列表
3、globbing
4、命令生成
练习:
1)、遍历ab、ac、ad列表,并输出



2)、编写脚本for01.sh,创建10个用户,如果用户已存在则不用创建(练习整数列表)



3)、编写脚本for02.sh,遍历/var/log/目录下所有文件(练习globbing)



4)、编写脚本for03.sh,列出所有用户的属组(练习命令引用生成列表)



5)、编写脚本for04.sh,算术运算,求100以内所以正整数之和;



6)、编写脚本for05-01.sh、for05-02.sh、for05-03.sh,算术运算,求100以内所有偶数之和;使用至少三种方法实现;







注意:增强型赋值算术运算:+=、-=、 *=、/=、 %=,如:sum=$[$sum+$i]等同于let sum+=$i
7)、编写脚本for05.sh,显示/etc目录下所有普通文件列表,而后统计一共有多少个文件;





8)、编写脚本for06.sh,写一个脚本,打印九九乘法表(练习循环嵌套)



for循环的特殊用法:
格式:for ((expr1;expr2;expr3)); do #expr1: 定义控制变量,并初始赋值;expr2: 循环控制条件;expr3: 修正控制变量
循环体
done
while循环
格式:expression条件为真进入循环体,expression为假退出循环
while expression;do
循环体
done

练习:
1)、编写脚本for07.sh,求100以内所有正整数之和(使用while循环)



2)、编写脚本for08.sh,打印九九乘法表



while循环的特殊用法:遍历文件的每一行
格式:while read VARIABLE; do
循环体
done < /PATH/FROM/SOME_FILE #/PATH/FROM/SOME_FILE文件路径

练习:
1)、编写脚本for09.sh,找出UID为偶数的所有用户,显示其用户名和ID号;




until循环:直到型循环
格式:expression条件为假进入循环体,expression为真退出循环,与for、while进入循环体的条件相反
until expression;do
循环体
done
练习:
1)、编写脚本until01.sh,求100以内所有正整数之和(使用until循环)




流程控制:continue、break
continue 语句用来跳过本次循环中的代码,直接跳回到循环的开始位置。如果条件为真则开始下一次循环,否则退出循环
break 语句可以结束while,for,until等结构的执行,即从结构中跳出。退出循环后,转到done语句后继续执行
格式:
while CONDITION; do
循环体
if CONDITION2; then
break

fi
done

while CONDITION; do
循环体
if CONDITION2; then
continue

fi
循环体
done
练习:
1)、编写脚本continue01.sh,求100以内所有齐数之和;




特殊循环:死循环
格式:
while true; do ---永远为真
循环体
if CONDTION; then
break
fi
done

until false; do ---永远为假
循环体
if CONDITION; then
break
fi
done

练习:
1)、编写脚本break01.sh,脚本进入死循环直至用户输入数字大于3。要跳出这个循环,返回到shell提示符下



2)、编写脚本break02.sh,每隔3秒钟查看当前系统上是否有名为“gentoo”的用户登录;如果某次查看gentoo登录了,则显示gentoo已经登录;如果未登录,就显示仍然未来,并显示这是已经是第多少次查看了;




bash shell用户可定义函数,然后在脚本中可以随便调用。函数最大作用就是让程序模块化,即把脚本文件中的代码分隔为多段,放在不同的文件中。
函数作用域:函数仅在定义的shell环境中有效,如果要传递函数给子shell环境使用,需要使用命令export及其选项-;同时函数中的变量默认是全局的。可用local将变量设置为函数私

有的。
语法:
[ function ] funname [()]

{
action;

[return int;]

}

1、可用function fun() 定义,也可直接fun() 定义,不带任何参数。
2、参数返回加:return;如不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)

练习:
1)、改造if04.sh脚本为fun01.sh,已函数来定义
#!/bin/bash
#
prog=$(basename $0)
lockfile="/var/lock/subsys/$prog"
#echo $lockfile
if [ $# -lt 1 ]; then
echo "Usage: $prog start|stop|restart|status"
exit 1
fi
start() {                                                                              #注意这里已函数来定义
if [ -f $lockfile ]; then
echo "$prog is started yet."
else
touch $lockfile && echo "Starting $prog ok..." || echo "Starting $prog failed..."
fi
}
stop() {
if [ -f $lockfile ]; then
rm -f $lockfile && echo "Stop $prog ok...." || echo "Stop $prog failed..."
else
echo "$prog is stopped yet."
fi
}
restart() {
if [ -f $lockfile ]; then
rm -f $lockfile && touch $lockfile && echo "Restarting $porg ok..."
else
touch $lockfile && echo "$prog is stopped, Starting $prog ok...."
fi
}
status() {
if [ -f $lockfile ]; then
echo "Running..."
else
echo "Stopped..."
fi
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo "Usage: $prog start|stop|restart|sttus"
exit 1
esac


2)、编写脚本fun02.sh,判断用户的ID号的奇或者偶数;




汇总练习:
1、写一个脚本:如果某路径不存在,则将其创建为目录;否则显示其存在,并显示内容类型;(不要怀疑,就是这么简单)



2、写一个脚本,完成如下功能;判断给定的两个数值,孰大孰小;给定数值的方法:脚本参数,命令交互;(使用read,依然如此简单)



3、求100以内所有奇数之和(至少用3种方法。是的这是我们的作业^_^)





4、写一个脚本实现如下功能:
(1) 传递两个文本文件路径给脚本;
(2) 显示两个文件中空白行数较多的文件及其空白行的个数;
(3) 显示两个文件中总行数较多的文件及其总行数;



5、写一个脚本:提示用户输入一个字符串;判断:如果输入的是quit,则退出脚本;否则,则显示其输入的字符串内容;



6、写一个脚本:打印2^n表;n等于一个用户输入的值;(不好意思,我调皮了)



7、写一个脚本,写这么几个函数:函数1、实现给定的两个数值的之和;函数2、取给定两个数值的最大公约数;函数3、取给定两个数值的最小公倍数;关于函数的选定、两个数值都将通过脚本参数进行输入。





bash shell之sed工具
sed工具:一种流编辑器,又称行编辑器,它一次处理一行内容。
工作原理:把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
定址:定址来定位所希望编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包括行数表示的那两行),0个行数指没有定址,处理文件的所有行。

如1,3表示1,2,3行,美元符号($)表示最后一行。
常用的语法格式:
(1)Sed [options] ‘script’ input_file…
(2)Sed [options] –f script_file input_file…
(3)Sed [options] ‘ADDR1,ADDR2command’ input_file…
常用选项:
-n:关闭默认输出,默认将自动打印所有行
-e script1 -e script2 -e script3:多点编辑,允许多个脚本指令被执行
-r:支持扩展正则
-i:可以修改原文件,慎用!
-f:支持使用脚本

定界符
#: 指定行;
$: 最后一行;
/regexp/:任何能够被regexp所匹配到的行;
\%regexp%:同上,只不过换作%为regexp边界符;
\%regexp%| :匹配时忽略字符大小写;
startline,endline:开始行,结束行
#,/regexp/:从#行开始,到第一次被/regexp/所匹配到的行结束,中间的所有行
/regexp1/,/regexp2/:从第一次被/regexp1/匹配到的行开始,到第一次被/regexp2/匹配到的行结束,中间的所有行
#,+n:从#行开始,一直到向下的n行
first~step:指定起始行,以及步进,如:1~2,2~2

常用命令选项
a\:在当前行下面插入文本
i\:在当前行上面插入文本
c\:把选定的行改为新的文本
d:删除,删除选择的行
s:替换指定字符
p:打印模板块的行
r:file 从file中读行
w:file 写并追加模板块到file末尾
=:打印当前行号码

常用替换标记
g:表示行内全面替换
\1:子串匹配标记
&:已匹配字符串标记

常用元字符
^:匹配行开始,如:/^abc/匹配所有以abc开头的行
$:匹配行结束,如:/abc$/匹配所有以abc结尾的行
.:匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d
*:匹配0个或多个字符,如:/*abc/匹配所有模板是一个或多个空格后紧跟sed的行
[]:匹配一个指定范围内的字符,如/[aa]bc/匹配abc和Abc
[^]:匹配一个不在指定范围内的字符,如:/[^A-RT-Z]bc/匹配不包含A-R和T-Z的一个字母开头,紧跟bc的行
\(..\):匹配子串,保存匹配的字符,如s/\(test\)able/\1rs,testable被替换成testlrs。
&:保存搜索字符用来替换其他字符,如s/test/**&**/,test这成**test**。
\<:匹配单词的开始,如:/\ 匹配单词的结束,如/test\>/匹配包含以test结尾的单词的行
x\{m\}:重复字符x,m次,如:/0\{5\}/匹配包含5个0的行
x\{m,\}:重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行
x\{m,n\}:重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行

练习:
1、把/tmp/test.txt下aaa替换成AAA,并且打印显示该行



2、删除/tmp/test.txt下空白行(注意元字符的应用)



3、删除/tmp/test.txt下空格开头的行




4、删除/tmp/grub.cfg文件中所有行的行首的空白字符



5、删除/tmp/fstab文件中所有以#开头,后跟至少一个空白字符的行的行首的#和空白字符



6、把/tmp/fstab文件的奇数行另存为/tmp/fstab.1



7、编写sed1.sh脚本,实现把tmp/test.txt中的大写字母D替换成小写的e(注意用-f选项)



8、echo一个文件路径给sed命令,取出其基名;进一步地,取出其路径名;




sed高级用法:保持空间(hold space),有相应的常用高级命令
h:用模式空间中的内容覆盖保持空间的内容
H:把模式空间中的内容追加至保持空间中内容的后面
g:从保持空间中取到其内容,并将其覆盖模式空间中的内容
G:从保持空间中取到其内容,并将其追加在模式空间中的内容的后面
x:把保持空间和模式空间中的进行交换
n:读取匹配到的行的下一行至模式空间(会覆盖模式空间中的原有内容)
N:读取匹配到的行的下一行至模式空间,追加在模式空间中原有内容的后面
d:删除模式空间中的内容
D:删除多行模式空间中的首行

练习:
1、在tmp/test.txt文件中的每行后方添加空白行



2、tmp/test.txt文件保留最后一行



3、删除/tmp/passwd第三行到末尾的数据,并把bash替换为zsh



4、保留/tmp/test.txt文件中的奇数行;



5、倒序排列tmp/test.txt文件



6、保留tmp/test.txt文件倒数2行



注意理解:$!N是对末尾行不执行N命令,其他行执行N命令
$!D是对末尾行不执行D命令,对其他行执行D命令
7、显示/tmp/fstab行号(注:场景比较少用,相对复杂了)



awk工具,一般指gawk:强大的文本分析工具,对数据分析并生成报告。awk是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
语法:
awk [options] 'program' {filenames}
awk '{pattern + action}' {filenames}
pattern:要查找的内容
action:找到匹配内容时所执行的一系列命令,常用的有:命令、控制语句、复合语句、输出(输入)语句等
花括号({}):不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组

awk内置变量与自定义变量
常用内置变量
$0:这个变量包含执行过程中当前行的文本内容
$n:前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段
FS:输入字段分隔符 默认是空格
NF:当前记录中的字段个数,就是有多少列
NR:已经读出的记录数,就是行号,从1开始
RS:输入的记录他隔符默 认为换行符
FNR:当前记录数
OFS:输出字段分隔符 默认也是空格
ORS:输出的记录分隔符,默认为换行符
ARGC:命令行参数个数
ARGV:命令行参数数组
FILENAME:当前输入文件的名字
自定义变量
使用-v选项,将外部值(并非来自stdin)传递给awk
练习:
1、输出tpm/passwd中第一字段和第七字段信息并且已分号隔开



2、显示文本tpm/passwd中所有超过50个字符的行号,并显示内容



注:$0表示整个记录(行)
3、统计/tmp/passwd后10行:文件名,每行的行号,每行的列数,对应的完整行内容



4、定义变量aaa,bbb,用awk输出变量




printf命令:标准格式输出命令,并不会自动加入换行符,如需换行需要手工加入换行符。而print命令是每个输出后自动增加一个换行符
语法:printf([format_control_flg],arg)
format_control_flg:格式
arg:区域
修饰符:
#:显示宽度
-:左对齐
+:显示数值的符号
.#: 取值精度
常见以下格式:
%c: 单个字符的ASCII码
%d, %i: 十进制整数
%e, %E: 科学计数法显示数值
%f: 浮点数
%g, %G: 以科学计数法格式或浮点数格式显示数值
%s: 显示字符串
%u: 显示无符号整数
%%: 显示%自身
练习:
1、显示磁盘情况并第一列默认右对齐



2、对2.2222取整



3、对2.2222取浮点数




awk输出重定向
>:重定向输出
>>: 重定向输出,不清空文件,只追加
| :打开一个管道输出到另一个命令进行操作
注意特殊文件输出输入描述符,简单了解即可:
/dev/stdin: 标准输入
/dev/stdout: 标准输出
/dev/stderr: 错误输出
练习:
1、把/tmp/test.txt如果第一个列的值等于4,则把它输出到outtest文件中



2、显示当前系统时间




awk操作符
算术操作符:+、-、*、/、**、^、%、负数(-)、正数(+)
字符串操作符:空格 (连接)
赋值操作符:=、+=、-=、*=、/=、%=、^=、**=、++、-- (注:模式自身是=号,写为/=/)
比较操作符:<、<=、>、=>、==、!=、~、!~
逻辑操作符:&&、||
条件表达式运算:要到问号和冒号,格式:表达条件式1 ?表达式2:表达式3;
相当于:
{
if (expression1)
expression2
else
expression3
}
练习:
1、输入两个数值10,20,进行比较,取最大值



注解:如果$1大于$2,则把问号后面的那个表达式的值赋给max,否则就将冒号后面那个表达式的值赋给max
2、输入两个数值10,20,进行比较,取最大值




awk数组
awk数组:关联数组(associative arrays),下标可以是数字也可以是字符串。awk中的数组不必提前声明,也不必声明大小,可初始化数组元素用 0 或空串
数字下标声明数组,如:
array[1]="her"
array[2]="your"
array[3]="sunday"
array[4]=2050
字符下标声明数组,如:
array["first"]="tom"
array["second"]="jack"
array["third"]="jerry"
删除数组:delete array[数组|字符]
遍历数组,需要使用特殊的结构:for (var in array) {for body}
练习:
1、统计tcp连接状态的个数($6也是最后一个字段,可以使用$NF)



2、统计/var/log/httpd/access_log访问所有本地的IP及个数




awk内置函数
主要有以下几种:算数函数、字符串函数、其它一般函数、时间函数
常用算术函数
exp( x ):返回 x 幂函数
sqrt( x ):返回 x 平方根
int( x ):返回 x 的截断至整数的值
常用字符串函数
split( String, A, [Ere] ):将string表示的字符串以A分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列
length([string]):返回string字符串中字符的个数
substr(string, start [, length]):取string字符串中的子串,从start开始,取length个;start从1开始计数
常用一般函数
getline [ Variable ]:将 Variable 参数指定的变量设置为从当前输入文件读取的下一个输入记录
常用时间函数
systime():取系统当前时间
练习:
1、显示所有tcp连接ip



awk函数调用
格式:function name(parameter1,parameter2,...) {return expression(表达式) }
练习:
1、求/tmp/function文件中三组整数的和




awk模式,常用有以下几种:
/正则表达式/:使用通配符的扩展集。
关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试
模式匹配表达式:用运算符~(匹配)和~!(不匹配)
BEGIN语句块、pattern语句块、END语句块

awk控制语句
条件判断:if-else
语法:if (condition) {then-body} else {[ else-body ]}
练习:
1、显示/tmp/test.txt文件中大于2列打印bad,小于100打印ok



2、显示/tmp/passwd文件中若用户是root则显示“admin”否则显示为“Common user”




循环语句:while、do-while、for、case
while循环语法: while (condition){statement1; statment2; ...}
do-whil循环语法:do {do-while body} while (condition)
for循环:for (variable assignment; condition; iteration process) {for body}
case语句语法:switch (expression) {case VALUE or /RGEEXP/: statement1;... default: stementN}
练习:(以下有多种实现方式,下面只是针对循环语句练习)
1、统计1-100的和(使用while语句)



2、统计1-100的和(使用do-while语句)



3、显示字符串小于等于4(使用do-while语句)



4、统计1-100的和(使用for语句)



5、显示字符串大于等于4的(使用for语句)



循环控制:continue、break、next
next:提前结束对本行文本的处理,并接着处理下一行
练习:
1、显示/tmp/fstab文件,i变量的初始值为3,若i小于可等于NF(当前记录中的字段数),则执行打印语句I am out!,且i增加1,若变量大于3则跳出循环



2、显示/tmp/test.txt文件,i变量的初始值为3,若i小于可等于NF(当前记录中的字段数),则执行打印语句please next lines,且i增加1,若变量等于0则跳出循环



3、显示/etc/passwd文件其ID号为奇数的用户:




本文出自 “一万小时定律” 博客,请务必保留此出处http://daisywei.blog.51cto.com/7837970/1696595
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: