位置变量参数
在向脚本传递参数时,可以使用此位置变量来获取参数。
他们分别是:
$0:脚本名字。此变量包含地址,可以使用basename $0获得脚本名称。
$1:第一个参数
$2,$3,$4,$5,...一次类推。
位置参数:
详见ABS(Advanced Bash Shell)中文翻译版103页第9章第一节内部变量,当然英文版ABS都一样啦
$0, $1, $2,等等...
位置参数,从命令行传递给脚本,或者是传递给函数.或者赋职给一个变量.
(具体见Example 4-5 和Example 11-15)
$0表示当前执行的进程名,script 本身的名字,或者在正则表达式中表示整行输出
$#
命令行或者是位置参数的个数.(见Example 33-2)
$*
所有的位置参数,被作为一个单词.
注意:"$*"必须被""引用.
$@
与$*同义,但是每个参数都是一个独立的""引用字串,这就意味着参数被完整地传递,
并没有被解释和扩展.这也意味着,每个参数列表中的每个参数都被当成一个独立的单词.
注意:"$@"必须被""引用.
其他的特殊参数
$-
传递给脚本的falg(使用set 命令).参考Example 11-15.
注意:这起初是ksh 的特征,后来被引进到Bash 中,但不幸的是,在Bash 中它看上去也不
能可靠的工作.使用它的一个可能的方法就是让这个脚本进行自我测试(查看是否是交
互的).
$!
在后台运行的最后的工作的PID(进程ID).
$_
保存之前执行的命令的最后一个参数.
$?
命令,函数或者脚本本身的退出状态(见Example 23-7)
用于检查上一个命令,函数或者脚本执行是否正确。(在Linux中,命令退出状态为0表示该命令正确执行,任何非0值表示命令出错。)
$$
脚本自身的进程ID.这个变量经常用来构造一个"unique"的临时文件名.
(参考Example A-13,Example 29-6,Example 12-28 和Example 11-25).
这通常比调用mktemp 来得简单.
注意事项:
[1] 当前运行的脚本的PID 为$$.
[2] "argument"和"parameter"这两个单词经常不加区分的使用.在这整本书中,这两个
单词的意思完全相同.(在翻译的时候就未加区分,统统翻译成参数)
退出和返回
退出状态(exit status)
函数返回一个被称为退出状态的值. 退出状态可以由return 来指定statement, 否则函数的
退出状态是函数最后一个执行命令的退出状态(0 表示成功,非0 表示出错代码). 退出状态
(exit status)可以在脚本中由$? 引用. 这个机制使脚本函数也可以像C 函数一样有一个"
返回值".
return
终止一个函数.return 命令[1]可选地带一个整数参数,这个整数作为函数的"返回值"返回
给调用此函数的脚本,并且这个值也被赋给变量$?.
while true可以写为while :
二)文本处理命令
改变字段分隔符
在g a w k中,缺省的字段分隔符一般是空格符或TA B。但你可以在命令行使用- F选项改变字符分隔符,只需在-
F后面跟着你想用的分隔符即可。
gawk -F" ;"'/tparker/{print}' /etc/passwd
• | 表示“或”。
例如:
/ c a t | C AT/
和cat 或C AT字符匹配。
• * 表示字符的零到多次重复。
例如:
/UNI*X/
和U N X、U N I X、U N I I X、U N I I I X等匹配。
• + 表示字符的一次到多次重复。
• ^ 表示字段的开始。
例如:
$3 ~ /^b/
如果第三个字段以字符b开始,则匹配。
• $ 表示字段的结束。
例如:
$3 ~ /b$/
如果第三个字段以字符b结束,则匹配。
• . 表示和任何单字符m匹配。
例如:
$3 ~ /i.m/
如果第三个字段有字符i,则匹配。
• + 表示字符的一次到多次重复
例如:
/UNI+X/
和U N I X、U N I I X等匹配。
• \{a,b\} 表示字符a次到b次之间的重复。
例如:
/ U N I \ { 1,3 \ } X
和U N I X、U N I I X和U N I I I X匹配。
• ? 表示字符零次和一次的重复。
例如:
/UNI?X/
和UNX 和U N I X匹配。
• [] 表示字符的范围。
例如:
/I[BDG]M/
和I B M、I D M和I G M匹配
• [^] 表示不在[ ]中的字符。
例如:
/I[^DE]M/
和所有的以I开始、M结束的包括三个字符的字符串匹配,除了IDM和IEM之外。
11.调用gawk程序
当需要很多对模式和动作时,你可以编写一个gawk程序(也叫做gawk脚本)。在gawk程序中,你可以省略模式和动作两边的引号,因为在gawk程序中,模式和动作从哪开始和从哪结束时是很显然的。
你可以使用如下命令调用g a w k程序:
gawk -f scrīpt filename
此命令使gawk对文件filename执行名为scrīpt的gawk程序。
如果你不希望使用缺省的字段分隔符,你可以在f选项后面跟着F选项指定新的字段分隔符(当然你也可以在gawk程序中指定),例如,使用分号作为字段分隔符:
gawk -f scrīpt -F";" filename
如果希望gawk 程序处理多个文件,则把各个文件名罗列其后:
gawk -f scrīpt filename1 filename2 filename3 ...
缺省情况下, gawk的输出将送往屏幕。但你可以使用Linux的重定向命令使gawk的输出送往一个文件:
gawk -f scrīpt filename > save_file
1. grep正则表达式元字符集(基本集)
^ 锚定行的开始 如:'^grep'匹配所有以grep开头的行。
$ 锚定行的结束 如:'grep$'匹配所有以grep结尾的行。
. 匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。
* 匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。
[] 匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。
[^]
匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。
\(..\) 标记匹配字符,如'\(love\)',love被标记为1。
\锚定单词的开始,如:'\匹配包含以grep开头的单词的行。
\> 锚定单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。
x\{m\} 重复字符x,m次,如:'0\{5\}'匹配包含5个o的行。
x\{m,\} 重复字符x,至少m次,如:'o\{5,\}'匹配至少有5个o的行。
x\{m,n\} 重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。
\w
匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,然后是p。
Grep命令选项
-? 同时显示匹配行上下的?行,如:grep -2 pattern filename同时显示匹配行的上下2行。
-c,--count 只打印匹配的行数,不显示匹配的内容。
-i,--ignore-case 忽略大小写差别。
-q,--quiet 取消显示,只返回退出状态。0则表示找到了匹配的行。
-n,--line-number 在匹配的行前面打印行号。
-s,--silent 不显示关于不存在或者无法读取文件的错误信息。
-v,--revert-match 反检索,只显示不匹配的行。
-w,--word-regexp 如果被\和\>引用,就把表达式做为一个单词搜索。
5. 实例
要用好grep这个工具,其实就是要写好正则表达式,所以这里不对grep的所有功能进行实例讲解,只列几个例子,讲解一个正则表达式的写法。
$ ls -l | grep '^a'
通过管道过滤ls -l输出的内容,只显示以a开头的行。
$ grep 'test' d*
显示所有以d开头的文件中包含test的行。
$ grep 'test' aa bb cc
显示在aa,bb,cc文件中匹配test的行。
$ grep '[a-z]\{5\}' aa
显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
$ grep 'w\(es\)t.*\1' aa
如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个es(\1),找到就显示该行。如果用egrep或grep
-E,就不用"\"号进行转义,直接写成'w(es)t.*\1'就可以了。
sed 是一种在线编辑器,它一次处理一行内容
4. 元字符集
^ 锚定行的开始 如:/^sed/匹配所有以sed开头的行。
$ 锚定行的结束 如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d。
* 匹配零或多个字符 如:,love这成**love**。 (&代表搜索的字符)
\ 锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。 x\{m\}
重复字符x,m次,如:/0\{5\}/匹配包含5个o的行。
x\{m,\} 重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。 x\{m,n\}
重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。
sed -n
's/^test/mytest/p'
example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。
sed
's/^192.168.0.1/&localhost/'
example-----&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加
localhost,变成192.168.0.1localhost。
sed 's#10#100#g'
example-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。
多点编辑:e命令
* $ sed -e '1,5d' -e
's/test/check/'
example-----(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执
行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果
sed
'/test/,/check/s/$/sed test/'
example-----对于模板test和west之间的行,每行的末尾用字符串sed test替换。
位置参数(Positional Parameters)
--------------------------------------------------------------------------------
所谓的位置参数便是0,1,2,3,4,5,6,7,8,9...。使用时,用$0,$1,$2...。
位置参数是当
script被载入时,後面所附加的参数。$0是本身,$1则为第一个参数,$2为第二个,依此类推。而当Positional
Parameters被 function所使用时,它们会被暂时取代(下一节会介绍function)。
例如以下这个script:
#!/bin/sh
# Filename : position
echo $0
echo $1
执行时:
[foxman@foxman bash]# ./position abc
./position
abc
当位置参数超过两位数时,有特别的方法来展开,称为Expansion。
--------------------------------------------------------------------------------
特殊参数(Speical Parameters)
这些符号,非常不人性,对新手来说很困扰。但上手後,会觉得方便无比,
有些如果您看不懂的话,就--算了,不用浪费太多时间在上面。
--------------------------------------------------------------------------------
* 星号
将Positional Parameters合成一个参数,其间隔为IFS内定参数的第一个字元(见内建变数一 节)。
例:
#!/bin/sh
# starsig
echo $*
执行:
[foxman@foxman bash]# starsig a b c d e f g
a b c d e f g
--------------------------------------------------------------------------------
@ at符号
与*星号类同。不同之处在於不参照IFS。
例:
#!/bin/sh
# atsig
echo $@
执行:
[foxman@foxman bash]# atsig a b c d e f g
a b c d e f g
--------------------------------------------------------------------------------
# 井字号
展开Positional parameters的数量。
例:
#!/bin/sh
# poundsig
echo $#
执行
[foxman@foxman bash]# poundsig a b c d e f g
7
--------------------------------------------------------------------------------
? 问号
最近执行的foreground pipeline的状态。
--------------------------------------------------------------------------------
- 减号
最近执行的foreground pipeline的选项参数。
--------------------------------------------------------------------------------
$ $
本身的Process ID。
[foxman@foxman bash]# ps ax | grep bash
1635 p1
S 0:00
/bin/bash
[foxman@foxman bash]# echo $$
1635
--------------------------------------------------------------------------------
! 惊号
最近执行背景命令的Process ID。
--------------------------------------------------------------------------------
0 零
在Positional Parameters一部份已经说明过了,是执行的shell script本身。但如果 是用"bash
-c",则$0被设为第一个参数。
[foxman@foxman bash]# echo $0
/bin/bash
--------------------------------------------------------------------------------
_ 底线符号
显示出最後一个执行的命令。
[foxman@foxman bash]# echo $_
bash
1.$0, $1, $2,等等:位置参数,从命令行传递给脚本,或者是传递给函数.或者赋职给一个变量.
2.$#:命令行或者是位置参数的个数.
3.$*:所有的位置参数,被作为一个单词.注意:"$*"必须被""引用.
4.$@:与$*同义,但是每个参数都是一个独立的""引用字串,这就意味着参数被完整地传递,并没有被解释和扩展.这也意味着,每个参数列表中的每个参数都被当成一个独立的单词.注意:"$@"必须被引用.
5.$-:传递给脚本的falg(使用set 命令).注意:这起初是ksh 的特征,后来被引进到Bash
中,但不幸的是,在Bash 中它看上去也不能可靠的工作.使用它的一个可能的方法就是让这个脚本进行自我测试(查看是否是交互的).
6.$!:在后台运行的最后的工作的PID(进程ID).
7.$_:保存之前执行的命令的最后一个参数.
8.$?:命令,函数或者脚本本身的退出状态
9.$$:脚本自身的进程ID.这个变量经常用来构造一个"unique"的临时文件名.
2012-11-10 22:52
Linux--位置参数,参数移位,随机数,数組,函数,函数递归(转)
位置参数:
linux
程序中会大量用到位置参数,位置参数就形如:
mkdir a b
c d e f g
在以上程序中
mkdir 它自己也是一个参数,它个参数用 $0 表示
后面的参数用 $1
(a) $2(b) $3 (c)
最多到
$10,如果超10,那要用 shift 进行参数移位
参数移位
参数移位就是把后面(右边)的参数,往前(左边)移动,最前面(左边)的参数
覆盖(删除)了,整个参数个数也会少1。
例:
a b c d e f g h
||
|| shift
||
b c d e f g h
||
|| shift
||
c d e f g h
||
|| shift
||
d e f g h
位置参数的表示:
$0 程序本身
$1 -
$10 第1个参数、第2个参数、第3个参数...第10个参数
$# 参数个数
$* 所有参数
例:写程序,打印输入指定个数的指定字符
如: xxx
* 5 --打5个*,xxx
是你的程序名
xxx #
10 --打10个#,xxx 是你的程序名
随机数:
RANDOM
echo
$RANDOM
生成
0-32767 间的随机数,要前生其它随机数,要用间接的方法了
例:生成 0-100 间的随机数
echo $[$RANDOM1]
例:生成 50-100 间的随机数
echo
$[$RANDOMQ+50]
数組
具有相同的名字,不同下票变量集合,如
a[1] a[2] ......
数組定义方法:
方法一:把所有值用小括号括起(值间空格分形),赋給一个变量
如: a=(1 2 3 a b c)
使用:使用它的具体元素,如: echo
${a[0]} echo
${a[5]}
方法二:直接给单个下标赋值
如:b[1]=5
b[10]=8
下标值查看:
echo ${b[*]} 显示所有值,但不会显示下标个数,和下标序号
echo
${#b[*]} 看有多少个值
命令行可以通过set 来看
例:利用随机数与数组产生随机验证码
定义数组:a=(1
2 3 4 .... X Y Z # ^ _)
产生随机数:n
利用随机数作数组下标取数: echo ${a[$n]}
函数:
在shell程序时,经常会遇到反复使用相同或相近的代码段,那这里我们可以将这些代
码,提取出来,构成函数。
函数的优点在于,1、让主程序变得简短。2、方便维护。
函数定义:
FUNCTION
function_name() {
}
function_name() {
}
函数返回值:
1、默认以函数最后一条命令返回返回(没有显示的为函数指定返回值时)
2、使用return返回值,只能返回 0-255
例:写个求2个数这和的函数
add()
{
sum=$[$1+$2]
return $sum
}
read -p
"输入第一个数: " x
read -p
"输入第二个数: " y
add $x
$y
echo
"x+y=$?"
3、在函数中使用echo
add2 ()
{
sum=$[$1+$2]
echo $sum
}
read -p
"输入第一个数: " x
read -p
"输入第二个数: " y
add2 $x
$y
echo
"x+y=`add2 $x $y`"
函数中的变量问题:
程序中使用的变量,我们把它分为全局变量和局部变量
全局变量
未作特别声明都是全局变量,主程序代码中定义的变量都是全局变量,全局变量的作用范围
是从它的定义处,到程序末尾
局部变量
定义的方法:local 变量名
局部变量的作用范围:只在定义它的函数有效,一般来讲函数中的变量都应该声明为局部变量
函数使用:
先定义、后使用,使用时输入函数名即可
FUNCTION 关键字
function_name 函数名
例:定义一个打印函数
function
my_print() {
commands
}
也可以
my_print() {
commands
}
例:定义一个打印指定个数*的函数
function
my_print() {
n=1
while [ $n -le $1 ]
do
echo -n "*"
n=$[$n+1]
done
}
my_print
5
例:定义一个打印指定个数,指定字符的函数
my_print
5 "*"
my_print 10 "#"
函数递归
自已调用自已
要点:
1、必须有个变量终值时的处理
2、递归调用时,变量值的变化要向终值靠近
#函数递归调用,求阶乘
function
jx() {
local n
if [ $1 -eq 1 ]
then
n=1
else
n=$[$1*`jx $[$1-1]`]
fi
echo $n
}
s=`jx
5`
echo
"5的阶乘是: $s"
517

被折叠的 条评论
为什么被折叠?



