Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2958939
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: 嵌入式

2014-08-29 19:17:04

原文地址:http://liufabin66688.blog.163.com/blog/static/13968548200882362122846/

该部分讲述的是shell编程方面的知识,以Bourne Shell为主,因为它是使用最广泛的,因而移植性最好,虽然功能不如现代许多其他版本的shell强大。

篇幅不大,只是一个简明手册,不具备系统性。

 

1.文件名生成通配符

在shell中,有两种类型的通配符:文件名生成通配符和正则表达式通配符。两者是不同的,注意区分。

字符*

星号*匹配文件名中的任何字符串。

字符?

?匹配文件名中的任何单个字符。

[…]和[!…]

使用[…]匹配方括号中的任何字符。可以使用一个横杠来连接两个字母或数字,表示一个范围。

使用[!…]表示非的意思。

 

2.正则表达式通配符

(1).基本元字符集
元字符 含义
^ 只匹配行首,在[]中表示否定
$ 只匹配行尾
* 一个单字符后紧跟*,匹配0个或多个此字符
[] 匹配[]内字符,可以是一个单字符,也可以是字符序列,可以使用-表示范围
\ 用来屏蔽一个元字符的特殊含义
. 匹配任意单字符
pattern\{n\} 用来匹配前面pattern出现次数,n为次数
pattern\{n, \} 含义同上,但次数最少为n
pattern\{n, m\} 含义同上,但次数在n与m之间
(2).\屏蔽的特殊字符

$ . ‘ “ * [ ] ^ | \ + ?

(3).例子
^$ 匹配空行
[A-Za-z] 匹配所有字母
[A-Za-z]* 匹配所有单词
[^A-Za-z] 匹配任一非字母型字符
A\{2, \} 匹配AAB、AAAB、…
[0-9]\{2\}-[0-9]\{2\}-[0-9]\{4\} 匹配dd-mm-yyyy

 

3.find命令

(1).find命令的形式:
find pathname -optino [ -pirnt -exec -ok ]

pahtname:查找的目录路径;

-print:将匹配的文件输出到标准输出;

-exec:对匹配的文件执行给出的shell命令,命令形式为‘command {} \;’,注意空格;

-ok:与-exec类似,在执行前会让用户确认。

(2).-name

按照文件名查找文件。

例:

查找$HOME目录及子目录下所有.txt文件:

find ~ -name "*.txt" -print

查找当前目录及子目录下以一个大写字母开头的文件:

find . -name "[A-Z]*" -print

查找/etc及子目录下以host开头的文件:

find  /etc -name "host*" -print

查找$HOME目录及子目录下文件:

find ~ -name "*" -print或find . -print

查找当前目录及子目录下以两个小写字母打头,后跟两个数字,最后是.txt后缀的文件:

find . -name "[a-z][a-z][0-9][0-9].txt" -print
(3).-perm

按照权限查找。

例:

查找当前目录及子目录下权限为755的文件:

find . -perm 755 -print

查找当前目录及子目录下所有用户都可读、写、执行的文件(使用八进制数字前要加-):

find . -perm -007 -print
(4).-prune

忽略某个目录,如果同时使用了-depth,则-prune被忽略。

例:

find /apps -name "/apps/bin" -prune -o -print
(5).-user和-nouser

-user:按照文件属主查找;

-nouser:查找文件属主帐户已经被删除的文件。

例:

查找属主为duan的文件:

find ~ -user duan -print

查找文件属主帐户已经被删除的文件

find /home  -nouser -print
(6).-group和-nogroup

-group:按照文件所属的组查找;

-nogroup:查找属于不存在的组的文件。

例:

查找属于用户组informix的文件

find /apps -group informix -print

查找不存在组的文件:

find / -nogroup -print
(7).-mtime

按更改时间查找,减号-限定更改时间距今n日内的文件,加号+限定更改时间距今n日外的文件。

例:

查找更改时间在5日内的文件:

find . -mtime -5 -print

查找更改时间在3日前的文件:

find . -mtime +3 -print
(8).-newer

查找更改时间新的文件,可以使用!逻辑非。

例:

查找比haha.txt新的文件:

find . -newer haha.txt

查找比haha.txt新但比find.txt旧的文件:

find . -newer haha.txt ! -newer find.txt -print
(9).-type

按类型查找。类型有:

  • b,块设备文件;
  • d:目录;
  • c:字符设备文件;
  • p:管道文件;
  • l:符号链接文件;
  • f:普通文件。

例:

查找目录文件:

find /etc -type d -print

查找非目录文件:

find . ! -type d -print

查找符号联接文件:

find /etc -type l -print
(10).-size

按照文件大小查找。单位是块,也可以是字节(后跟c)。

例:

查找字节大于1M的文件:

find . -size +1000000c -print

查找字节为100的文件:

find . -size 100c -print

查找大小大于10块的文件:

find . -size +10 -print

查找字节小于10的文件:

find . -size -10c -print
(11).-depth

先匹配所有文件,再在子目录中查找。

例:

先匹配当前目录中所有.txt文件,再在子目录中找:

find . -name "*.txt" -depth -print
(12).-mount

只在当前文件系统中查找,不进入其他文件系统。

例:

find . -name "*.txt" -mount -print
(13).-cpio

使用cpio命令将文件备份到磁带上。

例:

find etc home apps -depth -print -cpio /dev/rmt0
(14).-exec和-ok

对匹配的文件执行某操作。

例:

find logs -type f -mtime +5 -exec rm {} \;
find . -name "*.log" -mtime +5 -ok rm {} \;
find /etc -name "passwd*" -exec grep "rounder" {} \;
(15).和xargs结合使用
find . -name "*.txt -print |xargx file
find . -name "*.txt" -print | xagrs echo  >/tmp/tmpfile
find . -perm -7 -print |xargs chmod o-w
find . -type f -print |xargs grep "device"
find . -name \* -type f -print |xargs grep "DBO"

 

4.shell输入和输出

(1).echo命令

显示文本行或变量,缺省会自动换行。

特殊字符:

  • \c:不换行;

  • \f:进纸;

  • \t:跳格;

  • \n:换行。

有些系统使用echo的-n选项来控制不换行。

特殊字符使用\来转义,如双引号。

(2).read命令

read命令从标准输入读入一行信息,并将其赋给变量。如果只有一个变量,则整行内容都赋给此变量,若有多个变量,则把输入内容按空格分开分别赋给变量,多余的输入内容全部赋给最后一个变量。

read形式为:

read var1 var2 …
(3).cat命令

cat命令显示文件内容,使用选项-v可以显示控制字符。

如:

cat myfile
cat -v myfile
(4).tee命令

tee命令把输出的一个副本送到标准输出,另一个副本拷贝到相应的文件中。

如:

who | tee who.out;
who | tee -a who.out;-a表示追加到文件末尾。
(5).文件重定向

文件描述符0为标准输入,文件描述符1为标准输出,文件描述符2为标准错误。

常用重定向命令:

command >filename:把标准输出重定向到一个新文件中;
command >>filename:把标准输出重定向到一个文件(附加);
command 1>filename:把标准输出重定向到一个新文件中;
command >filename 2>&1:把标准输出和标准出错重定向到一个文件中;
command 2>filename:把标准错误重定向到一个新文件中;
command 2>>filename:把标准错误重定向到一个文件(附加);
command >>filename 2>&1:把标准输出和标准出错重定向到一个文件中(附加);
command < file >file2:以file为标准输入,以file2为标准输出;
command < filename:以filename为标准输入;
command << delimiter:从标准输入读入,直到遇到delimiter分界符;
command <&m:把文件描述符m作为标准输入;
command >&m:把标准输出重定向到文件描述符m中;
command <&-:关闭标准输入。
(6).exec命令

exec命令替换当前shell,它践踏了你当前的shell。

一个例外是exec对文件描述符操作时,它不覆盖当前shell。

使用exec操作文件描述符,例如:

exec 4<&0 0

把描述符4重定向到标准输入,把标准输入重定向到stock.txt。

exec 0<&4;

把描述符0重定向到描述符4,即恢复标准输入。

 

5.命令执行顺序

(1).使用&&

一般形式为:

命令1&& 命令2

含义:&&左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行。

如:

cp justice.doc justice.bak && echo "cp was OK"
(2).使用||

一般形式为:

命令1|| 命令2

含义:如果左边的命令(命令1)未执行成功,那么就执行||右边的命令(命令2)。

如:

cp wopper.txt oops.txt || echo "cp failed"
(3).使用()和{}组合命令

在当前shell执行一组命令,形式为:

(命令1;命令2;…)

在子shell中执行一组命令,形式为:

{命令1;命令2;…}

如:

comet month_end || (echo "hello" | mail dave; exit)

 

6.stty命令

stty用于设置终端特性。

(1).查询现有终端设置
stty -a
(2).设置tty选项
stty name character

如:

stty erase ^H

在vi中输入控制字符:先按ctrl-v,再按该控制字符。

(3).保存stty现有设置
stty -g

以可读形式保存stty现有设置,便于以后恢复。

如:

SAVETTY=`stty -g`
...
stty $SAVETTY

 

7.shell变量

(1).设置变量
  1. Variable_name = value,设置实际值到变量中;
  2. Variable_name + value,如果设置了变量,则使用value值,但不改变量的值;
  3. Variable_name :? value,如果未设置变量,显示用户错误信息value;
  4. Variable_name ? value,如果未设置变量,显示系统错误信息;
  5. Variable_name := value,如果设置了变量,则使用它,如果未设置变量,设置其值;
  6. Variable_name :- value,同上,但取值并不设置到变量中。

如:

echo "The file is ${FILES:?}"
echo "The file is ${FILES:?' sorry cannot locate the files'}"

COLOUR=blue
echo "The sky is ${COLOUR:-grey} today"
(2).显示变量

在变量名前加$,可以用{}将变量名括起来。如:

echo ${CREAT_PICTURE}
(3).清除变量

使用unset命令清除变量。

(4).显示所有本地shell变量

使用set命令。

(5).设置只读变量
variable_name=value
readonly variable_name
(6).查看所有只读变量

使用readonly命令。

(7).位置变量参数

传给脚本的参数可以使用如下变量进行访问,只有前9个可以直接访问,使用shift可以改变此限制:

$0、$1、$2、…、$9

其中$0为脚本名字,$1到$9为第一到第九个参数。

(8).特定变量参数

$#:传递到脚本的参数个数;

$*:以一个单字符串显示所有向脚本传递的参数;

$$:脚本运行的当前进程ID号;

$!:后台运行的最后一个进程的进程ID号;

$@:与$#类似;

$-:显示shell使用的当前选项,与set命令相同;

$?:显示最后命令的退出状态,0表示没有错误,其他任何值表明有错误。

 

8.环境变量

(1).设置环境变量
variable_name=value; export variable_name\
或\
variable_name=value\
export variable_name\
(2).查看所有环境变量

使用env命令。

(3).环境变量列表
CDPATH;
EXINIT;
HOME;
IFS;
LOGNAME;
MAIL;
MAILCHECK;
MAILPATH;
PATH;
PS1;
PS2;
SHELL;
TERMINFO;
TERM;
TZ;
EDITOR;
PWD;
PAGER;
MANPATH;
LPDEST/PRINTER。

 

9.引用

shell引用类型有:””双引号;’’单引号;`反引号;\反斜线。

(1).双引号

双引号可引用除字符$、`、\外的任意字符或字符串,这几个特殊字符是美元符号、反引号和反斜线,对shell来说,它们有特殊意义。

(2).单引号

类似于双引号,但shell会忽略任何引用值。

(3).反引号

反引号用于设置系统命令的输出到变量,shell将反引号的内容作为一个系统命令,并执行其内容。

(4).反斜线

反斜线屏蔽下一个字符的特殊含义。

具有特殊含义的字符:& * + ^ $ ` “ | ?。

如:

echo $$      显示当前进程ID号;
echo \$$      显示$$;
expr 12 \* 12  计算12乘以12;
echo “This is a copyright \251 sign”  显示八进制字符;

 

10.条件测试

(1).语法

使用test命令,形式如下:

test condition
或
[ condition ] (在括号和条件之间要有空格)

测试结果为0表示成功,其他为失败。

(2).逻辑操作符

-a 逻辑与,操作符两边都为真,结果为真,否则为假;

-o 逻辑或,操作符一边为真,结果为真,否则为假;

! 逻辑否,条件为假,结果为真。

(3).测试文件状态
-d   目录
-f   正规文件
-L   符号连接
-r   可读
-s   文件长度大于0、非空
-w   可写
-u   文件有suid位设置
-x   可执行

如:

test -w score.txt
[ -d appbin ]
[ -w b1.txt -a -w b2.txt ]
(4).字符串测试

字符串测试有5种格式:

test "string"
test string_operator "string"
test "string" string_operator "string"
[ string_operator string ]
[ string string_operator string ]

其中string_operator可为:

= 两个字符串相等;

!= 两个字符串不等;

-z 空串;

-n 非空串。

如:

[ -z $EDITOR ]
[ $EDITOR = "vi" ]
[ "$TAPE1" = "$TAPE2" ]
[ "$TAPE1" != "$TAPE2" ]
(5).数值测试

格式如下:

"number"  number_operator "number"
   or
[ "number" number_operator "number" ]

其中numbe_operator可为:

-eq 数值相等;

-ne 数值不等;

-gt 第一个数大于第二个数;

-lt 第一个数小于第二个数;

-le 第一个数小于等于第二个数;

-ge 第一个数大于等于第二个数。

如:

[ "$NUMBER" -eq "300" ]
[ "$NUMBER" -gt "300" ]
[ "$NUMBER" -gt "$SOURE_COUNT" ]
[ "99" -le "993" ]
(6).expr用法

expr命令一般用于数值计算,但也可用于字符串。格式如下:

expr argument operator argument

如:

expr 10 + 10
expr 30 / 3
expr 30 / 3 / 2
expr 30 \* 3   乘法要用反斜线
LOOP=0
LOOP=`expr $LOOP + 1`

可以用expr测试一个数,如果试图计算非整数,将返回错误:

$VALUE=hello
expr $VALUE + 10 >/dev/null 2>&1
echo $?  (失败)

expr还能比较字符串和进行模式匹配。expr的返回值成功为1,与系统的最后退出命令结果刚好相反,不要混淆。

 

11.控制流结构

(1).退出状态

退出shell使用如下命令:

exit n

其中n为退出状态,0表示成功,1表示失败。

(2).if then else语句

格式为:

if condition1
then        (if和then不在同一行)
  ....
elif condition2
then
  ....
else
  ....
fi
或:
if condition; then    (if和then在一行时要用分号)
  ....
fi

例如:

if [ “10” -le “12” ]
then
  …
fi
if grep david ha.txt >/dev/null 2>&1
then
  …
fi
(3).交互模式

测试脚本是交互模式还是非交互模式,使用test的-t选项,若测试成功,则为交互方式。如:

if [ -t ]; then
  echo “we are interactive with a terminal”
fi
(4).空语句

if语句各部分都不能为空,可以使用空命令解决这个问题。

空语句形式为一个冒号:。

if [ -z $DIR ]
then
  echo “DIR is empty”
else
  :    #do nothing
fi
(5).case语句

case语句格式:

case 值 in
模式1)
  命令1
  …
  ;;
模式2)
  命令2
  …
  ;;
esac

模式:

模式可以使用元字符:* ? [ ... ]。

模式中可以使用“|”作为或命令。

示例:

case $TERMINAL in
vt100|vt102)
  TERM=vt100
  ;;
vt200)
  TERM=vt200
  ;;
*)
  echo “not valid”
  exit 1
  ;;
esac
(6).for循环

for语句格式:

for 变量名 in 列表
do
  命令1
  命令2 …
done

列表:

省略in列表时,for接收命令行位置参数作为参数,等同于:

for param in “$@”
或
for param in “$*”

示例:

for loop in 1 2 3 4 5
for loop in “orange red blue grey”
for loop in `ls`
(7).until循环

until循环执行一系列命令直至条件为真停止。

until格式:

until 条件
  命令1
  …
done

条件测试发生在循环末尾,因此循环至少执行一次。

(8).while循环

while循环格式:

while 命令
do
  命令1
  命令2 ..
done

永真循环:

while :
do
  …
done
(9).使用break和continue

break允许跳出循环或case语句。如果在一个嵌套循环里,可以指定跳出的循环个数。如在两层循环里,用break 2刚好跳出整个循环。

continue跳过当前循环步,继续下一循环。

 

12.shell函数

(1).函数定义格式
function 函数名()
{
   命令1
   …
}
(2).函数参数

函数里使用参数就象在一般脚本中使用特殊变量$1、$2等一样。

(3).函数返回

函数结束可以用return返回函数执行结果:

return   从函数返回,用最后状态命令决定返回值;
return 0  无错误返回;
return 1  有错误返回。
(4).函数返回值测试

在脚本调用函数语句的后面使用最后状态命令测试函数的返回值。如:

check_is_directory $FILENAME
if [ “$?” = “0” ]
then
  …
fi

更好的方法是在if中测试。如:

if check_is_directory $FILENAME
then
  …
fi
(5).函数文件

文件的首行为#!/bin/sh。

装入函数文件格式:

. /pathname/filename

在shell中装入后,可以用set命令查看,用unset删除。

在脚本中装入后,可以在脚本中使用定义的函数。

 

13.脚本参数

(1).处理方式

脚本处理参数有三种方式:

  1. 使用特定变量$1、$2、...、$9,$#统计参数个数。此法的缺点是只能处理9个参数;
  2. 使用shift;
  3. 使用getopts。
(2).shift

shift的功能是每次将参数位置向左偏移一位,通过循环可以处理所有的参数。

如:

while [ $# -ne 0 ]
do
  echo $1
  shift
done
(3).获得命令行输入的最后一个参数

有两种方法:

  1. 使用命令:eval echo \$$#;
  2. 使用命令:shift `expr $#-2`。
(4).getopts

使用getopts可以处理复杂的命令行参数。

getopts的一般格式为:

getopts option_string variable

option_string:

所有选项字母组合成option_string;

若选项有取值,则在字母后加一个冒号,取值时,存放在OPTARG变量中;

使用自定义的错误信息,在option_string前加冒号,在处理语句(如case)中使用?创建一可用语句捕获错误。

如:

命令行为:-[a v] -[c value] file

while getopts :avc: OPTION
do
  case $OPTION in
  a)
    ALL=true
    echo "ALL is $ALL"
    ;;
  v)
    VERBOSE=true
    echo "VERBOSE is $VERBOSE"
    ;;
  c)
    COPIES=$OPTARG
    echo "COPIES is $COPIES"
    ;;
  \?)
    echo "`basename $0` -[a v] -[c value] file" >&2
    ;;
  esac
done

 

14.tput创建屏幕输出

(1).初始化终端

使用tput,需初始化终端,方法:

tput init
(2).输出类型

tput产生三种输出:字符型、数字型和布尔型(真/假)。

(3).字符串输出
bel 警铃
blink 闪烁模式
bold 粗体
civis 隐藏光标
clear 清屏
cnorm 不隐藏光标
cup 移动光标到屏幕位置(x,y)
el 清除到行尾
ell 清除到行首
smso 启动突出模式
rmso 停止突出模式
smul 开始下划线模式
rmul 结束下划线模式
sc 保存当前光标位置
rc 恢复光标到最后保存位置
sgr0 正常屏幕
rev 逆转视图
(4).数字输出
cols 列数目
it tab设置宽度
lines 屏幕行数
(5).布尔输出
chts 光标不可见
hs 具有状态行
(6).使用布尔输出
STATUS_LINE=`tput hs`
if $STATUS_LINE ; then
  echo "has a status line"
  …
fi
(7).使用字符型输出
BOLD=`tput bold`
REV=`tput rev`
NORMAL=`tput sgr0`
CURSOR_OFF=`tput civis`
CURSOR_ON=`tput cnorm`
tput init
echo $CURSOR_OFF
echo "${BOLD} WELCOME TO THE PIZZA ${NORMAL}"
echo "\n${REV}WE ARE OPEN 7 DAYS A WEEKS${NORMAL}"
echo $CURSOR_ON
(8).光标位置

用tput将光标放在屏幕任意位置,方法如下:

tput cup r c
(9).在屏幕中心位置显示文本
centertxt()
{
  _ROW=$1
  _STR=$2
  LEN=`echo $_STR | wc -c`
  echo $LEN
  COLS=`tput cols`
  echo $COLS
  NEW_COL=`expr \( "$COLS" - "$LEN" \) / 2`
  xy 10 $NEW_COL $STR
}
(10).在脚本中使用功能键

使用cat命令可获得任意特殊键控制序列(如F1,箭头等),方法:

cat -v回车,按任意键,回车,即获得功能键。

在脚本中使用这些控制键时要注意,不同系统取值可能不同。

uparrowkey=' [A'
downarrowkey=' [B'
echo -n "Press a control key then hit return"
read KEY
case $KEY in
$uparrowkey)
  echo "Up Arrow"
  ;;
$downarrowkey)
  echo "Down Arrow"
  ;;
esac
(11).使用颜色

颜色对应的数字:(不是所有颜色都适合所有系统)

前景色:

数字 颜色
30 黑色
31 红色
32 绿色
33 黄(棕)色
34 蓝色
35 紫色
36 青色
37 白(灰)色

背景色:

数字 颜色
40 黑色
41 红色
42 绿色
43 黄(棕)色
44 蓝色
45 紫色
46 青色
47 白(灰)色

显示颜色格式为:

 [ backgroud_number ; foreground_number m

在脚本中使用echo语句产生颜色:

colour()
{
  case $1 in
  black_green)
    echo "\033[40;32m"
    ;;
  black_yellow)
    echo "\033[40;33m"
    ;;
  black_white)
    echo "\033[40;37m"
    ;;
  black_cyan)
    echo "\033[40;36m"
    ;;
  black_red)
    echo "\033[40;31m"
    ;;
  esac
}

 

15.创建临时文件

临时文件和日志文件可以使用date命令或$$(当前进程ID)生成名字唯一的文件名。

 

16.发送信号

常用信号:

号码 名称 说明
1 SIGHUP 挂起或父进程被杀死
2 SIGINT 来自键盘的中断信号,如ctrl-c
3 SIGQUIT 从键盘退出
9 SIGKILL 无条件终止
11 SIGSEGV 段(内存)冲突
15 SIGTERM 软件终止(缺省杀进程信号)

发送信号使用kill命令:

kill [ -signal no | signal name ] process_id

 

17.trap信号捕获

对信号有三种处理方式:系统默认;忽略;捕获。

(1).捕获信号
trap “do_something” signal no(s)

如:

trap “my_exit” 2 3 (my_exit为一个函数或命令)
(2).忽略信号
trap “” signal no(s)

如:

trap “” 1 2 3 15
(3).恢复系统默认状态
trap signal no(s)

如:

trap 2 3

 

18.eval

eval首先扫描命令行进行所有的置换,然后再执行命令。该命令适用于那些一次扫描无法实现其功能的变量。

如:

显示文件testfile的内容:

MYFILE=”cat testfile”
eval $MYFILE

 

19.grep

(1).一般格式
grep [选项] 基本正则表达式 [文件]

这里正则表达式可以为字符串。在命令中输入字符串参数时,最好用双引号括起来。在调用模式匹配时,应使用单引号。

(2).grep选项

-c,只输出匹配行的计数

-i,不区分大小写(只适用于但字符)

-h,查询多文件时不显示文件名

-l,查询多文件时只输出包含匹配字符的文件名

-n,显示匹配行及行号

-s,不显示不存在或无匹配文本的错误信息

-v,显示不包含匹配文本的所有行

(3).国际字符匹配模式的类名形式
等价的正则表达式
[[:upper:]] [A-Z]
[[:lower:]] [a-z]
[[:digit:]] [0-9]
[[:alnum:]] [0-9a-zA-Z]
[[:space:]] 空格或TAB键
[[:alpha:]] [a-zA-Z]
(4).例子
grep -c "sort" *.dat

输出匹配sort的行数。

grep '^[^48]' data.f

匹配不以49开头的行。

grep '6\{2,6\}' file.h

匹配6出现2-6次的行。

grep '5[[:upper:]][[:upper:]]' data.f

匹配5后跟两个大写字母的行。

 

20.awk

(1).命令格式

有三种方式:

  1. 命令行方式:

    awk [ -F 域分隔符 ] ‘commands’ input_file(s)

    域分隔符不指定时缺省为空格,commands是awk命令语句。

  2. awk脚本方式。
  3. awk命令文本方式:

    awk -f awk_script_file input_file(s)

(2).awk语句的构成

awk语句都由模式和动作组成。模式决定何时进行操作,动作是操作的具体内容。

模式可以是任何条件语句或复合语句或正则表达式。有两个特殊模式:BEGIN和END。BEGIN在任何文本浏览动作之前,END使用在完成文本浏览之后。

实际动作在{}中指定,简单如打印,复杂的如控制和循环等。

(3).域和记录

awk执行时,其浏览域用$1、$2、…、$n标识,多个域之间用逗号分隔,如$1,$3。

$0标识整个记录(整行)。

(4).awk中的正则表达式

除了基本的元字符外,awk中还可以使用如下两个字符:

+,匹配一个或多个字符;

?,匹配模式出现频率。

(5).awk条件操作符
操作符 描述 操作符 描述
< 小于 >= 大于等于
<= 小于等于 ~ 匹配正则表达式
== 等于 !~ 不匹配正则表达式
!= 不等于

要匹配一个正则表达式,可以使用~后紧跟/正则表达式/,也可使用if语句,if后面的条件用()括起来。

如:

awk '{if ($4 ~ /Brown/) print $0}' grade.txt
awk '$4 ~ /Brown/ {print $0}' grade.txt
(6).复合条件操作符

&&:语句两边必须同时匹配为真。

||:语句两边同时或其中一边为真。

!:求逆。

如:

awk '{if ($1 == "P.Bunny" && $4 == "Yellow") print $0}' grade.txt
awk '{if ($4 == "Yellow" || $4 ~ /Brown/) print $0}' grade.txt
(7).awk内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME Awk正在浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行-F选项
NF 浏览记录的域个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符

访问命令行参数的方法:ARGV[n]。

访问系统环境变量:ENVIRON[ “EDITOR” ] = “vi”。

FNR表示awk目前操作的记录数,其值小于等于NR。

NF表示记录域个数,在记录被读之后设置。

OFS允许指定输出域分隔符,缺省为空格。

ORS允许指定输出记录分隔符,缺省为新行(\n)。

RS为记录分隔符,缺省为新行(\n)。

例:

显示记录个数:

awk 'END {print NR}' grade.txt

文件非空时才操作:

awk '{if (NR > 0 && $4 ~ /Bronw/) print $0}' grade.txt

显示路径中的文件名:

echo “/usr/sybase/etc/rc.file”  |awk -F/ '{print $NF}'
(8).awk其他操作符
= += -= *= /= %= ^= 赋值操作符
? 条件表达操作符
+ - * / % ^ 算术操作符
++ -- 前缀和后缀

在awk中可以设置变量。如:

awk '{name=$1; belts=$4; \
if (belts ~ /Yellow/) print name" is belt "belts}' grade.txt
(9).awk内置字符串函数
gsub(r,s) 在整个$0中用s替代r
gsub(r,s,t) 在整个t中用s替代r
index(s,t) 返回s中字符串t的第一位置
length(s) 返回s的长度
match(s,r) 测试s是否包含匹配r的字符串
split(s,a,fs) 在fs上将s分成序列a
sprintf(fmt,exp) 返回经fmt格式化后的exp
sub(r,s) 在$0中用最左边最长的子串s替代r
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分

使用举例:

awk 'gsub(/4842/,4899) {print $0}' grade.txt
awk 'BEGIN {print index("Bunny","ny")}' grade.txt
awk '$1 == "J.Troli" {print length($1)" "$1}' grade.txt
awk 'BEGIN {print length("A good man")}'
awk 'BEGIN {print match("ABCD", /d/) }'
awk 'BEGIN { print split("123#456#678", myarray, "#"); \
 print myarray[1]; print myarray[2]; print myarray[3])}'
awk "$1 == "J.Troli" {sub(/26/, "29", $0); print $0}' grade.txt
awk '$1 == "L.Tanskey" {print substr($1, 1, 5)}' grade.txt
awk '{print substr($1, 3)}' grade.txt
(10).字符串屏蔽序列

\b    退格键

\f    走纸换页

\n    新行

\r    回车键

\t    tab键

\ddd  八进制值

\c    任意其他特殊字符,如\\为反斜线

(11).awk输出函数printf

基本语法: printf( [格式控制项],参数)

格式控制类似与c语言中的printf函数。

例如:

awk 'BEGIN { printf "%f\n", 999}'
awk 'BEGIN {print "Name\t\tS.Number"} \
{printf "%-15s %s\n", $1, $3 }'
(12).在命令行向awk传值

格式:

awk 命令变量=输入值。

如:

df -k |awk '($4 ~ /^[0-9]/) \
 { if ($4 < TRIGGER) print $6"\t"$4}' TRIGGER=5600
who |awk '{ if ($1 == user) print $1"connected to "$2}' \
user=$LOGNAME
(13).awk数组

数组使用前不用定义,一般使用循环来访问数组。格式:

for ( element in array ) print array[element]

 

21.sed

(1).命令格式

调用sed有三种格式:

  1. 命令行格式:

    sed [选项] sed命令 输入文件

  2. 使用sed脚本文件:

    sed [选项] -f sed脚本文件 输入文件

  3. 可执行sed脚本:

    sed脚本 [选项] 输入文件

    当没有输入文件时,sed从标准输入中接收输入。sed不会对原始输入文件做修改。

sed命令要用单引号括起来。

sed选项:

n:不打印,sed不写编辑行到标准输出,缺省为打印所有行(编辑和未编辑)。

c:无用。

f:调用脚本文件。

(2).sed定位文本的方式
x x为一行号,如1
x,y 表示行号范围从x到y,如2,5
/pattern/ 查询包含模式的行
/pattern/pattern/ 查询包含两个模式的行
pattern/,x 在给定行号上查询包含模式的行
x,/pattern/ 通过行号和模式查询匹配行
x,y! 查询不包含指定行号x和y的行

sed模式匹配使用正则表达式。

(3).基本sed编辑命令
p 打印匹配行
= 显示文件行号
a\ 在定位行号后附加新文本信息
i\ 在定位行号后插入新文本信息
d 删除定位行
c\ 用新文本替换定位文本
s 使用替换模式替换相应模式
r 从另一个文件中读文本
w 写文本到一个文件
q 第一个模式匹配完成后退出或立即退出
l 显示与八进制ASCII码等价的控制字符
{} 在定位行执行的命令组
n 从另一个文件中读文本下一行,并附加在下一行
g 将模式2粘贴到/pattern n/
y 传送字符
n 延续到下一输入行,允许跨行的模式匹配

例如:

显示文本1到3行:

sed -n '1,3p' quote.txt

显示匹配的行:

sed -n '/Neave/p' quote.txt

在第四行查询模式:

sed -n '4,/The/p' quote.txt

匹配元字符(使用反斜线屏蔽含义):

sed -n '/\$/p' quote.txt

显示整个文件:

sed -n '1,$p' quote.txt

打印模式匹配的行号:

sed -n '/music/=' quote.txt

删除匹配的文本行:

sed '/Neave/d' quote.txt

写入文件/从文件读:

sed '/Neave/w dht' quote.txt
sed '/company/r sedex.txt' quote.txt

匹配后退出:

sed '/.a.*/q' quote.txt

显示文件中控制字符:

sed -n '1,$l' func.txt
(4).附加文本

附加文本的操作格式(附加文本中的\表示换行,最后一行不加\,表示结束):

[address]a\
text\
text\
text

插入文本、修改文本与此类似。

(5).替换文本

格式:

[address[,address]] s/pattern-to_find/replace_pattern/[g p w n]

替换选项:

g,缺省替换第一次出现,使用g替换所有出现。

p,打印。

w 文件名,将输出结果写到文件。

如:

sed -n 's/night/NIGHT/p' quote.txt

附加或修改原匹配模式,可以使用(&)命令,&保存发现模式。

将nurse改为”Hello” nurse:

sed -n 's/nurse/"Hello" &/p' quote.txt

 

22.tr

(暂缺)

 

23.合并与分割

(1).sort (2).uniq (3).join (4).cut (5).paste (6).spli

阅读(1353) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~