SHELL编程学习笔记

SHELL编程学习笔记

       本文描述unix shell的各种应用实例,根据查阅资料和自我总结,作为自己今后复习的模板。本文搜集整理常用的shell应用实例,以例子详述unixshell部分命令的使用,着重于正则表达式以及grep、sed、awk等命令,涵盖业务开发中需要使用到的unix shell编程命令,供查阅或者自测使用,面向已经熟悉UNIX基本操作的开发人员。

注:  

文中大部分表达式在sco-unixunixware 7下使用sh测试通过,有些规则或表达式不能通过测试或结果不正确,在本文档中使用波浪下划线将其标出,使用时应注意验证其在不同shell下的表现。

注:sco-unixunixware 7是操作系统的一个分类。

SCO UNIX是SCO公司(SantaCruz Operation Inc)所研制的多用户、多任务的功能齐全的网络操作系统,具有稳定性强、可靠性高、安全性好等诸多优点,在各行各业中的应用十分广泛。

本文不是命令手册,所以除部分命令如grep、sed、awk外,本文不详述讲述命令的各个参数,查看命令参数请使用man命令,本文着重于以实际例子讲述命令特征。

命令格式

一.shell与Unix平台

Unix平台

shell

FreeBSD3.4

/bin/sh

SGI IPIX6.5

/sbin/sh

HUPX-11

usr/bin/sh

UnixWare 7

$SHELL或/bin/sh

Solaris 8 (固有的)

/usr/bin/sh

Solaris 8 (标准的)

/usr/bin/ksh

IBM AIX 4.3

/usr/bin/sh

IBM AIX 4.3 (可信的)

/usr/bin/tsh

Linux

/bin/sh

 

二.shell基本知识

脚本参数:

shell脚本参数可以任意多,但只有前9各可以被访问,使用shift命令可以改变这个限制。参数从第一个开始,在第九个结束。

$0 这个程序的执行名字

$n 这个程序的第n个参数值,n=1..9

$* 这个程序的所有参数

$# 这个程序的参数个数

$$ 这个程序的PID

$! 执行上一个背景指令的PID

$? 执行上一个指令的返回值

其他参数:

$HOME  注册时进入的目录

$PATH  命令的搜索目录

$PS1   系统第一个提示符,一般为$

$PS2   系统第二个提示符,一般为>

$LINENO   所在的代码行,一般用来输出错误行号

shift [n]     将命令行参数往左移一位,但$0不变

export 变量名表    将变量名表所列变量传递给子进程

read  变量名表    从标准输入读字符串,传给指定变量

echo   变量名表    将变量名表指定的变量显示到标准输出

set        显示设置变量

env        显示目前所有变量

 

set命令可以重新设定参数表.如set hello  wold命令会设定$*为字符串hello world,$n和$#也同时受影响。

shift命令可以将所有参数左移一个单位,$*、$n、$#均受影响。

 

数组(在sh中不支持):

${#varlist[@]}       数组元素个数

${datalist[index]}   数组元素

${#datalist[index]}  数组元素长度

    执行命令:

1)  command:直接执行命令command

2)  sh command:启动一个shellprocess执行命令command

3)  .  command:在本process中执行命令command

4)  execcommand:本Script将会被所执行的命令所取代,当这个命令执行完毕之後,本Script也会随之结束。

 

二.chmod命令

格式:  chmod [who]operator[permission] filename

[who]:

u 文件属主权限。

g 同组用户权限。

o 其他用户权限。

a 所有用户(文件属主、同组用户及其他用户)。

operator:

+ 增加权限。

- 取消权限。

= 设定权限

[permission]:

r 读权限

w 写权限

x 执行权限

s 文件属主和组set -ID

t 粘性位* (不考虑)

l 给文件加锁,使其他用户无法访问

 

chmod –R -h…   //递归子目录, 遇到链接文件时不影响目标文件

目录的权限:

(1) r-可以列出目录内容; w-在目录中创建文件; x-目录可以搜索和访问

(2) 如果目录权限—x,目录中有一个可执行脚本,还是可以执行的

(3) 目录的权限会覆盖目录中文件的权限

 

三.grep命令

    搜索文本的匹配内容。

    格式:  grep  [-option] pattern  [filename]

选项:

    -c  只输出匹配行的计数

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

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

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

    -n  显示匹配行及行号

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

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

 

四.sed

    查找和编辑文本。

    格式:

(1)直接键入命令

sed  [-option] command_line  filename

(2)将sed命令插入脚本文件,然后调用sed

sed  [-option] -f  program_file  filename

(3)将sed命令插入脚本文件,并使脚本可执行

sed  program_file [-option]  filename

选项:

n 不打印;sed不把编辑行写到标准输出,默认为打印所有行(编辑的和未编辑的)。p命令可以用来打印编辑行。

    c  下一个命令是编辑命令。在使用多项编辑时要加入该选项。

   f  如果正在调用sed脚本,要使用此选项。此选项同志sed脚本支持所有的sed命令。

 

 

五.awk命令

    awk是一种程序语言,对于资料的处理具有很强的功能,对于文档里的资料做修改、比较、抽取等处理,awk能够以很短的程序轻易地完成。如果使用C 语言写程序完成上述的操作不方便且很花费时间,所写的程序也会很大。

    awk能够依照用户定义的格式来分解输入的资料也可以依照用户定义的格式来打印资料。

    awk可用于在对象文件中逐行读取记录,按照命令中定义的匹配模式寻找相关记录,然后对该记录进行操作动作。

格式:

(1)直接键入命令:

awk  [-Fchar] ‘command_line’  filename

(2)将awk命令插入脚本文件,然后调用awk:

awk  -f program_file  filename

       前一种形式的-Fchar确定间隔符,command_line为操作动作,filename为对象文件。

       后一种形式的program_file是指用户按一定格式编制好的对对象文件的匹配与操作。

 

六.find命令

通过文件名或其它特征查找文件。

格式:

    find [path-list] [predicate-list]

选项:

    -type  tp  文件类型为tp:

       b   块特别文件

       c   字符设备特别文件

       d   目录文件

       f   普通文件

       p   管道文件(FIFO)

       s   socket

       I   符号链接文件

    -user uname  文件属于用户uname。

    -group gname  文件属于组gname。 

    -size  n   文件是n块大小(每块512字节),若n后跟一个c,单位为字节。

    -atime n      在n天内已访问过此文件。

    -mtime n      在n天内已修改过此文件

    -ctime n      在n天内文件被修改、属性(拥有者、组、链接数等)被修改。

    -exec  command{} \;  执行命令

    -print        打印当前路径名

    -newer file   修改时间比file文件晚

 

七.test命令

命令格式

testexpression

expression中包含一个以上的判断准则以作为test评诂的标准。两准则间用"-a"代 表逻辑AND 运算,"-o"代表逻辑OR运算,而在准则前放置一"!"代表NOT 运算。如 果没有括号,则优先权则为"!"> "-a" > "-o" 。和expr命令相同,相使用左右括 号时,必须在其前面加上"\"。以下是有关准则的叙述(符合叙述时传回真,否则传回伪):

stringstring不为空白字串

-nstring string的长度大於0

-zstring string的长度等於0

string1=string2 string1等於string2

string1!=string2 string1不等於string2

int1 -gt int2 int1大於int2

int1 -ge int2 int1大於等於int2

int1 -eq int2 int1等於int2

int1 -ne int2 int1不等於int2

int1 -le int2 int1小於等於int2

int1 -lt int2 int1小於int2

-r filename 档案可读取

-w filename 档案可写入

-x filename 档案可执行

-f filename 档案为一般档

-d filename 档案为目录

-s filename 档案为非空的一般档

test -r "$filename" -a -s "$filename"

   

.expr命令

命令格式

expr expression

    expression是由字串以及运算子所组成,每个字串或是运算子之间必须用空白隔开 。下表是运算子的种类及功能,而优先顺序则以先後次序排列,可以利用小括号来改变运算的优先次序。其运算结果则输出至标准输出上。

:字串比较。比较的方式是以两字串的第一个字母开始,而以第二个字串的 字母结束。如果相同时,则输出第二个字串的字母个数,如果不同时则传 回0 。

*乘法

/除法

%取馀数

+加法

-减法

<小於

<=小於等於

=等於

!=不等於

>=大於等於

>大於

&AND运算

|OR运算

当expression中含有"*", "(",")" 等符号时,必须在其前面加上"\",以免被 Shell解释成其它意义。 

expr2 \* \( 3 + 4 \) 其输出为14

     

九.流程控制语法

    1. if then 语法

if(condition)

then

     then-commands

fi

    2. if then else 语法

if(condition)

then

     then-commands

else

     else-commands

fi

       3. ifthen elif语法

if(condition1)

then

    commands1

elif(condition2)

then

     commands2

else

     commands3

fi

 

    4. for in 语法

for varin arg-list

do

     commands

done

    5. for 语法

for var

do 

     commands

done

       例如

for arg

do

     echo $var

done

调用 varlist.sh 111 222 3333

输出: 111

       222

       333

    6. while 语法

while(condition)

do

     commands

done

 

    7. until 语法

until(condition)

do

     commands

done

 

    8. break及continue

这两者是用於for,while, until 等循环控制下。break 会跳至done后方执行 ,而continue会跳至done执行,继续执行循环。

 

    9. case 语法

case strin

     pat1)

        commands1

        ;;

     pat2)

        commands2

        ;;

esac

而pat 除了可以指定一些确定的字串,也可以指定字串的集合,如下

* 任意字串

? 任意字元

[abc] a,b, 或c三字元其中之一

[a-n] 从a到n的任一字元

| 多重选择,如A|a

 

十.shell脚本调试

    1.启动调试

启动调试Shell脚本的基本语法为:

    $/bin/sh option script arg1 arg2 ... argN

这里显式声明了要执行脚本的Shell为/bin/sh,script是脚本的名字,arg1到argN是脚本的参数, option为调试选项,如下所示:

    -n   读所有的命令,但不执行它们

    -v   在读时显示所有的行

-x   在执行时显示所有命令和它们的参数。该选项常称为shell 跟踪选项或

改变脚本的第一行,象下面那样在该行声明一个调试选项:

#!/bin/sh option

 

    2.使用set命令

       在每个调用激活调试模式中,调试模式的缺省行为对脚本中从第一行到最后一行都有效。有时我们只需要调试特定的函数或脚本的一部分,这时调试整个脚本就有些多余。通过使用set命令,我们可以在shell脚本的任何地方启动或取消调试,其基本语法为:

set[-|+] option

这里的option选项与上面的相同。

 

    3.语法检查

       在处理任何Shell脚本时,应在准备执行它之前检查脚本的语法,这使我们能改正许多问题。要启动语法检查可使用-n选项,如对于上面的buggy.sh脚本,象下面那样检查语法:

       $/bin/sh-n ./buggy.sh

   


实例讲解

一.模式匹配

1.ls显示所有以hosts.开头的文件

ls  –l  hosts.*

 

2.ls显示包含x,y,z字符的所有文件

       ls  –d  *[x-z]*

   

二.正则表达式

    1.grep匹配/etc/services文件中以ftp字符串开头的哪些文本行

grep   ‘^ftp’ /etc/services

 

    2.grep匹配以system文本结尾的行。

       grep   ‘system$’  file

 

    3.grep匹配仅包含一个#字符的行。

       grep   ‘^#$’  file

 

    4.grep匹配以或者[abc]开头的行

       grep   ‘[[<]abc[]>]’ file

 

    5.grep匹配以Ftp或者ftp开头的行

       grep   ‘^[Ff]tp’  file

 

    6.grep匹配F或者f以外的字符

       grep   ‘[^Ff]’    file

 

    7.grep匹配除大写字符以外的字符

       grep   ‘[^A-Z]’   file

 

    8.grep匹配以ftp或telnet开头的文本行

       grep   ‘^ftp|^telnet’    file

 

    9.grep匹配以ftp开头,后跟0个或多个-agent的文本行

       grep   ‘^ftp(-agent)?’   /etc/services

或  grep   ‘^ftp(-agent)*’   /etc/services

注:

    a)在scounix下,上面的单括号前要加转义符\

    b)在sunos 5.8下,不论加不加单括号均不支持。

 

    10.grep匹配以ftp开头,后跟1个或多个-agent的文本行

       grep   ‘^ftp(-agent)+’   /etc/services

       说明同上。

 

    11.grep匹配带有数字6,后跟至少3个0的文本行(使用-E启用边界特性)

       grep   -E  ‘60\{3,\}’ /etc/services

 

    12.grep匹配含有(abc)的文本

       grep   ‘\(abc\)’  file

 

    13.常用正则表达式举例

正则表达式

匹配功能

^[the]

以the开头行

[Ss]igna[lL]

匹配单词signal,signaL,Signal,SignaL

[Ss]igna[lL]\.

同上,但加一个句点

[mayMAY]

 

^USER$

只包含USER的行

[tty]$

以tty结尾的行

\.

带句点的行

^d..x..x..x

对用户、用户组及其它用户组成员有可执行权限的目录

^[^l]

排除关联目录的目录列表

[.*0]

0之前或之后加任意字符

[000*]

000或更多个

[iI]

大写或小写I

[iI][nN]

大写或小写I或n

[^$]

空行

[^.*$]

匹配行中任意字符

^……$

包括6各字符的行

[a-zA-Z]

任意单字符

[a-z][a-z]*

至少两个小写字母

[^0-9\$]

非数字或美元表示

[^0-9A-Za-z]

非数字或字母

[123]

1到3中的一个数字

[Dd]evice

单词Device或device

De..ce

前两个字母为De,后跟两个任意字符,最后为ce

^.$

仅有一个字符的行

^\.[0-9][0-9]

以一个句点和两个数字开始的行

“’Device’”

单词Device

De[Vv]ice\.

单词Device.或DeVice.

[0-9]\{2\}-[0-9]\{2\}-[0-9]\{4\}

日期格式dd-mm-yyyy

[1-9][0-9]\{1,2\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}

IP地址格式nnn.nnn.nnn.nnn

[^.*$]

匹配任意行

 

    14.grep精确匹配:在抽取字符串后加\>。

       grep  “48\>” file

 

    15.grep消除大小写:加入-i选项

       grep  -I  “sept”  file

 

    16.特殊字符:$ . ‘ “ * [ ] ^ | \ + ?

       如果要查询这些字符,需要在前面加转义字符\。

 

    17.grep判断变量含有[HOST]字符串

       if[ "1" -eq "`echo "$VarName" | grep -c'\[HOST\]'`" ]; then

   

    18.grep判断变量含有[xxx]字符串

       if[ "1" -eq "`echo "$VarName" | grep -c '\[.*\]'`"]; then

   

    19.grep匹配后缀为c,h,j,s,cpp,hpp的文件

EXT_ALL='chjs'

EXT_PP='ch'

EXT_NO_PP='js'

ls $1 | grep"\.[$EXT_ALL][p]\{0,2\}$" | grep -v "\.[$ EXT_NO_PP][p]\{1,2\}$" | grep -v "\.[$EXT_PP][p]\{1\}$" 

 

    20.正则表达式语法

    来自msdn,仅供参考。

Here aresome examples of regular expressions:

    Expression

Matches

/^\s*$/

Match a blank line.

/\d{2}-\d{5}/

Validate an ID number consisting of 2 digits, a hyphen, and an additional 5 digits.

/<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\1\s*>/

Match an HTML tag.

The following table contains thecomplete list of metacharacters and their behavior in the context of regularexpressions:

Character

Description

\

Marks the next character as a special character, a literal, a backreference, or an octal escape. For example, 'n' matches the character "n". '\n' matches a newline character. The sequence '\\' matches "\" and "\(" matches "(".

^

Matches the position at the beginning of the input string. If the RegExp object'sMultiline property is set, ^ also matches the position following '\n' or '\r'.

$

Matches the position at the end of the input string. If the RegExp object'sMultiline property is set, $ also matches the position preceding '\n' or '\r'.

*

Matches the preceding character or subexpression zero or more times. For example, zo* matches "z" and "zoo". * is equivalent to {0,}.

+

Matches the preceding character or subexpression one or more times. For example, 'zo+' matches "zo" and "zoo", but not "z". + is equivalent to {1,}.

?

Matches the preceding character or subexpression zero or one time. For example, "do(es)?" matches the "do" in "do" or "does". ? is equivalent to {0,1}

{n}

n is a nonnegative integer. Matches exactly n times. For example, 'o{2}' does not match the 'o' in "Bob," but matches the two o's in "food".

{n,}

n is a nonnegative integer. Matches at least n times. For example, 'o{2,}' does not match the "o" in "Bob" and matches all the o's in "foooood". 'o{1,}' is equivalent to 'o+'. 'o{0,}' is equivalent to 'o*'.

{n,m}

M and n are nonnegative integers, where n <= m. Matches at leastn and at most m times. For example, "o{1,3}" matches the first three o's in "fooooood". 'o{0,1}' is equivalent to 'o?'. Note that you cannot put a space between the comma and the numbers.

?

When this character immediately follows any of the other quantifiers (*, +, ?, {n}, {n,}, {n,m}), the matching pattern is non-greedy. A non-greedy pattern matches as little of the searched string as possible, whereas the default greedy pattern matches as much of the searched string as possible. For example, in the string "oooo", 'o+?' matches a single "o", while 'o+' matches all 'o's.

.

Matches any single character except "\n". To match any character including the '\n', use a pattern such as '[\s\S]'.

(pattern)

A subexpression that matches pattern and captures the match. The captured match can be retrieved from the resulting Matches collection using the$0$9 properties. To match parentheses characters ( ), use '\(' or '\)'.

(?:pattern)

A subexpression that matches pattern but does not capture the match, that is, it is a non-capturing match that is not stored for possible later use. This is useful for combining parts of a pattern with the "or" character (|). For example, 'industr(?:y|ies) is a more economical expression than 'industry|industries'.

(?=pattern)

A subexpression that performs a positive lookahead search, which matches the string at any point where a string matchingpattern begins. This is a non-capturing match, that is, the match is not captured for possible later use. For example 'Windows (?=95|98|NT|2000)' matches "Windows" in "Windows 2000" but not "Windows" in "Windows 3.1". Lookaheads do not consume characters, that is, after a match occurs, the search for the next match begins immediately following the last match, not after the characters that comprised the lookahead.

(?!pattern)

A subexpression that performs a negative lookahead search, which matches the search string at any point where a string not matchingpattern begins. This is a non-capturing match, that is, the match is not captured for possible later use. For example 'Windows (?!95|98|NT|2000)' matches "Windows" in "Windows 3.1" but does not match "Windows" in "Windows 2000". Lookaheads do not consume characters, that is, after a match occurs, the search for the next match begins immediately following the last match, not after the characters that comprised the lookahead.

x|y

Matches either x or y. For example, 'z|food' matches "z" or "food". '(z|f)ood' matches "zood" or "food".

[xyz]

A character set. Matches any one of the enclosed characters. For example, '[abc]' matches the 'a' in "plain".

[^xyz]

A negative character set. Matches any character not enclosed. For example, '[^abc]' matches the 'p' in "plain".

[a-z]

A range of characters. Matches any character in the specified range. For example, '[a-z]' matches any lowercase alphabetic character in the range 'a' through 'z'.

[^a-z]

A negative range characters. Matches any character not in the specified range. For example, '[^a-z]' matches any character not in the range 'a' through 'z'.

\b

Matches a word boundary, that is, the position between a word and a space. For example, 'er\b' matches the 'er' in "never" but not the 'er' in "verb".

\B

Matches a nonword boundary. 'er\B' matches the 'er' in "verb" but not the 'er' in "never".

\cx

Matches the control character indicated by x. For example, \cM matches a Control-M or carriage return character. The value ofx must be in the range of A-Z or a-z. If not, c is assumed to be a literal 'c' character.

\d

Matches a digit character. Equivalent to [0-9].

\D

Matches a nondigit character. Equivalent to [^0-9].

\f

Matches a form-feed character. Equivalent to \x0c and \cL.

\n

Matches a newline character. Equivalent to \x0a and \cJ.

\r

Matches a carriage return character. Equivalent to \x0d and \cM.

\s

Matches any white space character including space, tab, form-feed, and so on. Equivalent to [ \f\n\r\t\v].

\S

Matches any non-white space character. Equivalent to [^ \f\n\r\t\v].

\t

Matches a tab character. Equivalent to \x09 and \cI.

\v

Matches a vertical tab character. Equivalent to \x0b and \cK.

\w

Matches any word character including underscore. Equivalent to '[A-Za-z0-9_]'.

\W

Matches any nonword character. Equivalent to '[^A-Za-z0-9_]'.

\xn

Matches n, where n is a hexadecimal escape value. Hexadecimal escape values must be exactly two digits long. For example, '\x41' matches "A". '\x041' is equivalent to '\x04' & "1". Allows ASCII codes to be used in regular expressions.

\num

Matches num, where num is a positive integer. A reference back to captured matches. For example, '(.)\1' matches two consecutive identical characters.

\n

Identifies either an octal escape value or a backreference. If \n is preceded by at leastn captured subexpressions, n is a backreference. Otherwise, n is an octal escape value if n is an octal digit (0-7).

\nm

Identifies either an octal escape value or a backreference. If \nm is preceded by at leastnm captured subexpressions, nm is a backreference. If \nm is preceded by at leastn captures, n is a backreference followed by literal m. If neither of the preceding conditions exists, \nm matches octal escape valuenm when n and m are octal digits (0-7).

\nml

Matches octal escape value nml when n is an octal digit (0-3) andm and l are octal digits (0-7).

\un

Matches n, where n is a Unicode character expressed as four hexadecimal digits. For example, \u00A9 matches the copyright symbol (©).

 

三.sed命令

    sed的正则表达式用//括住。

    1.sed文本的定位方法:

x

x为一行号

x,y

表示行号范围从x到y

/pattern/

查询包含模式的行

/pattern/pattern/

查询包含两种模式的行

/pattern/,x

在给定行号上查询包含模式的行

x,/pattern/

通过行号和模式查询匹配行

x,y!

查询不包括指定行号x和y的行

 

    2.sed编辑命令

命令

意思

p

打印匹配行

=

显示文件行号

a/

在定位行号后附加新文本信息

i/

在定位行号后插入新文本信息

d

删除定位行

c/

用新文本替换定位文本

s

使用替换模式替换相应模式

r

从一个文件中都文本

w

将文本写道一个文件

q

第一个模式匹配完成以后退出或立即退出

l

显示八进制ASCII代码等价的控制字符

{}

在定位行执行的命令组

n

从另一个文件中读文本下一行,并附加到下一行

g

将模式2粘贴到/pattern n/

y

传送字符

   

    3.sed打印文件的第二行

       sed  -n  ‘2p’  filename

 

    4.sed打印文件的第一到三行

       sed  -n  ‘1,2p’  filename

 

    5.sed打印匹配test的行

       sed  -n  ‘/test/p’  filename

 

    6.sed打印匹配$的行

       sed  -n  ‘/\$/p’  filename

 

    7.sed打印最后一行:$是代表最后一行的特殊字符 

       sed  -n  ‘$p’  filename

 

    8.sed脚本文件

       #!/bin/sed  –f “/company/” a/ “The  suddenly it  happen.”

       将以上脚本保存为append.sed,使用chmod给予其可执行权限。使用append.sed  filename运行。脚本的执行将会在filename文件中查找company,在匹配行的后一行中附加新文本,输出到屏幕上(不改变原文件)。

 

    9.sed上例中如果将a\改为i\:

则为插入,在匹配行的前一行中附加新文本,输出到屏幕(不改变原文件)。

 

10.sed上例中如果将a\改为c\:

则为替换,匹配行被替换为新文本。

 

    11.sed删除第一行

       sed  ‘1d’  filename

 

    12.sed删除第一到第三行

       sed  ‘1,3d’ filename

 

    13.sed删除最后一行

       sed  ‘$d’ filename

 

    14.sed替换文本

       sed  ‘s/night/NIGHT/’  filename #将所有night替换为NIGHT

       sed  ‘s/night//’ filename          #将night删除

 

    15.sed输出到文件,w选项:

把第1到2行的内容输出到文件field中,不存在则创建。

       sed  ‘1,2w field’ filename        

 

    16.sed从文件读取,r选项:

把文件内容附加到匹配行company.之后

       sed  ‘/company./r sedex.txt’  filename

 

    17.sed优势:

用户在获得不同格式的、带有各种奇形怪状格式控制符的文本,需要将它编成易读的文本时,就可以使用sed流编辑程序。另外,在重新处理具有比较固定格式的文本以生成新格式的文本时,也可以使用sed流编辑程序。

 

    18.sed常见的一行命令集

命令

意思

‘s/\.$//g’    

删除以句点为结尾行

‘-e/abcd/d’

删除包含abcd的行(疑为’/abcd/d’)

‘s/[ ][ ]*/[ ]/g’

删除一个以上空格,用一个空格代替

‘s/^[ ][ ]*//g’

删除行首空格

‘s/\.[ ][ ]*/[]/g’

删除句点后跟两个或多个空格,用一个空格代替

‘s/^$/d’

删除空行(sh不支持d,但在ksh下支持)

‘s/^.//g’

删除第一个字符

‘s/COL\(…\)//g’

删除COL以及其后的三个字母

‘s/^\///g’

删除开头的/

‘s/[ ]*/[ ]/g’ 

删除所有空格并用tab代替

‘s/^[ ]//g’

删除行首的一个tab

‘s/^[ ]*//g’

删除行首的所有tab

‘s/[ ]*//g’

删除所有tab

‘s/[ ]*/[ ]/g’

删除所有tab并用一个空格代替

‘s/[ ][ ][ ][ ]*/[ ]/g’

每四个空格删除并使用一个tab代替

 

    19.sed去掉字串变量前后的空格

    str1=”  1234 “

str2=` echo ${str1} `

此时str2不含有前后的空格。

如果使用sed如下:

str2=”` echo ${str1} | sed ‘s/^[ ]*//g’| sed ‘s/[ ]*$//g’  `”

如果使用awk如下:

str2=”` echo $(str1) | awk ‘{print $1}’`”

或:

str2=”` echo $(str1) | sed ‘s/(^\s*) |(\s*$)//g’  `”

 

注:使用awk和sed的缘故是可以和前一次的操作一次性完成,而不必单独使用一条语句去除空格。例如下面第二个awk的作用就是去除空格:

TmpInf1="`echo $TmpInf | awk -F='{print $2}' | awk '{print $1}'`"

   

    20.sed去除文件count中的前后的空格

       tmp=`sed's/^ *//g' count | sed 's/ *$//g' `

       则tmp为文件内容,不含有前后的空格。

 

    21.sed提取最后一个目录名,

例如从../../etc/passwd或者/etc/passwd得到passwd

方法一:使用临时文件

#得到当前路径,输出到a文件

     pwd >a

     #读取a文件,过滤首字母/和尾字母/,将结果输出到b文件

sed 's/^\///g' a  | sed ‘s/\/$//g’ >b

   while fgrep \/ b

do

#读取b文件,过滤首字符串xxxx/,将结果输出到a文件

sed 's/^[a-zA-Z0-9]*\///g' b >a

#将a文件拷贝到b文件

   cp -f a b

done

rm –f a

rm –f b

 

方法二:使用变量(优于文件形式)

           c_path=`pwd`

           #过滤首字母/和尾字母/

c_path=`echo$c_path | sed 's/^\///g'  | sed‘s/\/$//g’ `

while [ `echo $c_path | grep -c '\/'`-gt 0  ]

do

c_path=`echo$c_path | sed 's/^[a-zA-Z0-9_.]*\///g'`

done

echo $cur_path

方法三:使用basename命令

           c_path=`pwd`

           c_path=`basename$c_path`

       注:参数扩展见五.5

 

    22.dirname或参数扩展提取目录名

       例如从$0参数中提取运行的路径:从../../etc/passwd/得到../../etc,从/etc/passwd得到/etc

       方法一:dirname

           c_path=$0

           c_path=`dirname$c_path`

注:如果没有路径,则c_path得到为单字符”.”。所以,判断是否在当前路径执行可以使用条件 “-$c_path”= “-.”

       方法二(参数扩展在基本sh下不支持):

           c_path=$0

           c_path=’${0%/*}’

注:如果没有路径,则c_path得到为文件名,即$0。所以,判断是否在当前路径执行可以使用条件 “-$c_path” = “-$0”

 

    23.grep,sed获取文件的扩展名

例如从../../home/file.c得到c

       方法一:

           file=$1

           #得到最后一级文件名 ,如file.c

file=`basename$file`

#如果文件名中不含有.,则表示没有后缀

if[ 1 -gt `echo $file | grep -c '\.'` ]; then

    echo "no extion"

else

    #过滤掉最后一个.以及之前的所有字符,得到扩展名

    echo `echo $file  | sed "s/.*\.//g" `

fi

       方法二:(参数扩展在基本sh下不支持)

           file=$1

           #得到最后一级文件名 ,如file.c

file=`basename $file`

#从file的尾部开始删除匹配.*(一个.后跟若干字符)的最小部分并返回剩余部分

           echo "${file%.*}" 

          

 

四.awk命令

1.awk字段分隔符:

 -F选项指定了字段分隔符为冒号

       awk  -F: ‘{print $1,$3}’  file

 

2.awk匹配模式

       分为三类:

a)  awk的关系表达式:

用来说明字段是否与要求符合。例如:$1==”char”、$2>20等等。

b)  awk地正则表达式:

用//括住。规则与sed相同。

例如:

           /^.$/  匹配只有一个字符的行。

c)  awk的BEGIN和END模式:

BEGIN模式意味着在读取第1行之前的匹配模式。它常用于初始化,例如设置分隔符、打印标题以及变量赋初值等。END模式是在处理完所有记录行以后的匹配模式。它常常用于输出结果。

 

3.awk“模式匹配-动作”

    a)在每一行中匹配’foo’,若匹配则打印该行

awk  ‘/foo/ {print $0}’ filename

b)在每一行中匹配第一个字段是否为’foo’, 若匹配则打印该行

           awk  ‘$1~/foo/ {print $0}’  filename

 

4.awk内部变量

(部分变量需要验证)

变量

含义

默认值

属性

ARGC

命令行实参个数

-

只读

ARGV

命令行实参数组

-

可读可写

FILENAME

当前输入文件名

-

只读

FNR

当前文件中的记录数

-

只读

FS

输入字段分隔符

空白及制表符

可读可写

NF

当前记录中的字段数

-

只读

NR

至今读取的记录数

-

只读

OFMT

数的输出格式

%.6g

可读可写

OFS

输出字段分隔符

空白

可读可写

ORS

输出记录分隔符

换行符

可读可写

RS

输入记录分隔符

换行符

可读可写

RSTART

由match()匹配的第一个字符索引

-

只读

RLENGTH

由match()匹配的串的长度

-

只读

SUBSEP

下标分隔符

“\34”

只读

CONVFMT

数值的内部转换格式

%.6g

可读可写

   

5.awk用户定义变量

       用户自定义变量用以存放数据以及进行运算。

 

6.awk算术运算

   算术运算在内部以浮点形式完成,也包含一般的加、减、乘、除、余和乘幂,运算符分别为”+”、”-“、”*”、”/”、”%”和”^”。

a)  awk  ‘$1==”Feb” {sum=$2+$3}  END{print sum}’  filename

b)  awk  ‘$1==”ATOM” {a=a+$2;i=i+1}’  filename

c)   

7.awk高级算符

       ++或者+=等等。

       awk‘$1==”ATOM” {a+=$2;i++}’   filename

 

8.awk内部算术函数

函数名

返回值

cos(x)

x的余弦值,x是弧度

exp(x)

x的幂函数

int(x)

x的整数部分

log()

x的自然对数

rand()

得出一个随机数,此随机数平均分布在0 和1 之间。这个值不会是0,也不会是1。

每次执行awk, rand 产生相同的随机数序列。

sin(x)

x的正弦值,x是弧度

sqrt(x)

x的平方根

srand(x)

x是针对rand()的新的种子。设定产生随机数的开始点或seed 随机数种子为x。如果在第二次你设定相同的seed 值,你将再度得到相同序列的随机数如果省略参数x,则现在的日期时间会被当成seed。这个方法可使得随机数是真正不可预测的srand 的。

  返回值(return value)是前次所设定的seed 值

 

9.awk内置函数

awk的字符串使用引号括起。通过连接常量、变量、数组元素、函数和其它表达式可以创建串表达式。

例如:打印第几号记录和一个冒号,然后打印文本行。

           {printNR”:”$0}

函数名

返回值

gsub(r,x)

在当前记录中,用s替换r,返回替换数

gsub(r,s,t)

在串t中,用s替换r,返回替换数

index(s,t)

返回s串中t的位置,不出现时为0

length(s)

返回s的长度

match(s,r)

返回r在s中出现的位置,不出现时为0

split(s,a)

针对FS把s分成数组a,返回字段数

split(s,a,r)

针对r把s分成数组a,返回字段数

sprintf(fmt,expr_list)

根据格式串fmt返回经过格式编排的expr_list

sub(r,s)

在当前记录中把第一个r替换成s,返回替换数

sub(r,s,t)

在t中把第一个r替换成s,返回替换数

substr(s,p)

返回从位置p开始的s的后缀

substr(s,p,n)

返回从位置p开始长度为n的s子串

注:

p最小为1,当p为0时,p被置为1;

n个字符包括p所在字符。

举例:

echo "abced" | awk '{print substr($1,2,2)}'

返回 bc

system(cmd)      

执行命令并返回出口状态

toupper(s)

将输入参数s中的字符全部转换为大写字符并返回转换后的字符串

tolower(s)

将输入参数s中的字符全部转换为小写字符并返回转换后的字符串

close( expr )

关闭由expr表示的文件或管道,文件或管道可能被print、printf语句或调用内建函数getline打开。如果成功,函数返回0,否则返回非0值

getline

这个内建函数将$0设置为当前输入文件的下一个输入记录,getline <  file将用从file中获得下一条记录修改$0的值,getline x用下一行的内容替换变量x,而$0仍然是当前行的内容。但下一次返回的将是下下一行的内容。cmd | getline将从管道中获得cmd命令的输出。如果成功,getline返回1,遇到文件结尾,getline返回0,出错返回-1。

 

 

   

10.awk的自定义函数

       格式:

       function  func_name(arg_list)

       {

}

例如:

将下列代码保存在awk_pro文件中,调用echo5 | awk –f awk_pro,将得到输出:5!is120。

functionfact(n)

{  

    if(n<=1)  

       return 1  

    else  

       return n*fact(n-1)  

}     

{print$1”!is” fact($1)}

数组实参可以通过应用传递,所以针对该函数有可能改变数组元素或创建一个新元素。标量实参将用值传递,形式参数是局部变量,但其它变量都是全局量。

 

11.awk的“下一”语句:

next语句 、nextfile 语句 、exit 语句

next语句强迫awk立刻定制处理目前的记录而继续下一个记录。

nextfile类似next,它强迫awk立刻定制处理目前的数据文件。

exit语句会使得awk程序停止执行而跳出。如果END出现,它会去执行END的动作。

 

12.awk中的字符串相加:

       str3为str + str2 + str

    str="hello""world"

    str2="----- "

    str3=str str2 str  

 

13.awk的逻辑运算符

    表达式

含义

x==y

x等于y时为真

x>y

x大于y时为真

x>=y

x大于或等于y时为真

x

x小于y时为真

x<=y

x小于或等于y时为真

x!=y

x不等于y时为真

x~y

x包含y时为真

x!~y

x不包含y时为真

 

 

    例如:

        awk '$2~"aaa" {print $0}' filename

 

14.awk的逻辑与||、逻辑或&&

       awk '$2=="bbb" || $2=="ccc"{print $0}' filename

awk '/2400/ && /foo/'BBS-list

awk '/2400/ || /foo/' BBS-list

awk '!/foo/' BBS-list

 

15.awk的FS、OFS和ORS使用:

以’|’为分隔符输出各个域

       awk‘BEGIN{OFS=”|”}{print $1,$2,$3,$4}’ filename

           awk 'BEGIN {OFS=";";ORS="\n\n"} {print $1, $2}' filename

       awk'BEGIN {FS=","}; {print $2}'

 

16.awk的sprintf函数的使用

sprintf格式化字符串

       print sprintf("%03d",2);

 

17.awk的重定向,输出到文件:

可以使用>或者>>

       print "This is a test" >"fff.txt"

 

18.awk删除文件的第一行

       awk ‘{ if(NR % 2 == 1)  printf “%s”, $0 ’

 

19.awk删除输入行中特定行的换行字符

       例如:删除奇数行的换行字符

        awk'

{

if (NR % 2 == 1)

printf "%s",$0 ;

else

print $0

}'

 

20.awk获取输入行中,域的最大个数

awk '{if (NF > max) max = NF} END{print max}'

 

21.awk输出一行超过80个字符的每一行

awk 'length($0) > 80'

 

22.awk输出至少一个域的所有行。可用来将一个文档里的所有空白行删除

awk '{if (NF > 0) print}'

 

23.awk输出范围在0到100 之间的7个随机数

awk 'BEGIN {for (i = 1; i <= 7;i++)

print int(101 * rand())}'

 

24.awk将所有用户的login名称依照字母的顺序输出

awk 'BEGIN {FS = ":"} {print$1 | "sort"}' /etc/passwd

 

25.awk将一个文档的总行数输出

awk '{nlines++} END {printnlines}'

或awk 'END {print NR}'

 

26.awk输出文档的内容时会在每行的最前面输出行号它的功能与'cat-n' 类似

awk '{print NR,$0}'

 

27.awk自定义函数的例子一: 第一个域与第二个域的平方和

awk ‘{print "sum=",SquareSum($1,$2)}

function SquareSum(x,y) {

sum=x*x+y*y

return sum

}’

28.awk的split、数组、注释

    test.awk文件:

#!/bin/awk-f

BEGIN{

    record="123#456#789"

    num=split(record,myarray,"#")

}

END{

    for(i=1;i<=num;i++)

    {

        print myarray[i]    # print the element of array

    }

}

   调用:

   ./test.awk    /dev/null

   输出:

123

456

789

五.其它命令

    1.eval命令:可用于动态生成和执行代码

       foo=10

       x=foo

       eval       y=’$’$x

       echo  $y

       输入10,即eval y=’$’$x被解释为y=$foo,即y=10。

nDay1="111"

nDay2="222"

nDay3="333"

# 遍历变量nDay1 ...nDay3,打印其值

for i in 1 2 3

do

    n=$i

    evalnVar='$nDay'$i

    echo $nVar

done

 

    2.exit n:退出

       0代表成功,1-125代表出错代码,128以上引发一个信号。

 

    3.export命令:

       把参数变量名导出到子shell里,使之成为子shell的环境变量。

       存在a.sh和b.sh两个shell脚本,在a.sh中调用b.sh,a.sh使用export输出的变量将成为b.sh的环境变量。

       使用set –a 或者set–allexport将把在它之后声明的任何变量导出为环境变量。

 

    4.shift命令:

       把所有参数变量向下移动一个位置。

       while[ "$1" != "" ];

do

    echo "$1"

    shift

done

 

    5.参数扩展:

      tmp_1="1111"

tmp_2="2222"

fori in 1 2

do

    eval tmp='$'tmp_${i}

    echo $tmp

done

其中,tmp_${i}为参数扩展的应用。常见参数扩展替换见下表:

参数扩展

说明

${param:-default}

若param空,则把它设为default的值

${#param}

给出param的长度

${param%word}

从param的尾部开始删除匹配word的最小部分并返回剩余部分(sh不支持,ksh支持)

${param%%word}

从param的尾部开始删除匹配word的最大部分并返回剩余部分(sh不支持,ksh支持)

${param#word}

从param的头部开始删除匹配word的最小部分并返回剩余部分(sh不支持,ksh支持)

${param##word}

从param的头部开始删除匹配word的最大部分并返回剩余部分(sh不支持,ksh支持)

 

例:将某个文件夹下所有gif文件通过cjpeg程序转换为jpeg文件。

forimage in *.gif

do

    cjpeg  $image  > $(image%%gif)jpg

done

 

例如:

FILE_NAME=${0##*/}   程序的文件名(不带路径)

BASE_DIR=${0%/*}     程序的路径

其它实例可参见三.22

 

    6.<<即时文档

       开始是”<<”,然后是特殊字符序列,该序列将在文档结尾再次出项。注意,结束的!FUNKY!最好顶格,前后不要留空格。

       cat<

       hello

       thisis a here

       !FUNKY!

 

    7.sh调试选项

       使用”-o”设置选项,使用”+o”取消设置。

 

命令行选项

set命令选项

说明

sh -n

你可能感兴趣的:(Linux)