admin管理员组

文章数量:1566998

2024年7月16日发(作者:)

Linux shell

1.1 shell变量

为使shell编程更有效,系统提供了一些shell变量。变量可以定制用户本身的工作环境。使

用变量可以保存有用信息,使系统获知用户相关设置;变量也用于保存暂时信息。

有两种变量:本地变量 和 环境变量。

(1)本地变量

本地变量在用户现在的Shell生命期的脚本中使用。

要设置一本地变量,格式为: variable-name = value or ${variable-name=value}

定义变量:可以使用export 来定义导出一变量,export variable-name=”variable-value”

显示变量:使用echo命令可以显示单个变量值,echo $variable-name

清除变量:使用unset命令清除变量,unset variable-name

显示所有变量:使用set 显示所有本地定义的shell变量;使用env显示所有shell变量。

例子:

$ export MYNAME=”hongdy”

$ echo $MYNAME

hongdy

$ env

$ set

$ unset MYNAME

(2)环境变量

环境变量用于所有用户进程(子进程),登录进程为父进程。Shell中执行的用户进程均为子进

程 。最好在.profile中定义,系统在/etc/profile文件中已经设置了一些环境变量。

设置环境变量:使用export导出环境变量,export VARIABLE-NAME

显示环境变量:使用echo命令可以显示环境变量,echo $(VARIABLE-NAME)

清除环境变量:使用unset命令清除环境变量,unset VARIABLE-NAME

显示所有环境变量:env显示所有环境变量

下面显示的是Shell的一些基本环境变量

变量

SHELL

TERM

TZ

HOME

UID

PWD

PS1

PS2

说明

变量保存缺省shell ,在/etc/passwd中设置

保存终端类型

时区变量保存时区值

用于保存注册目录的完全路径名

当前用户的标识符,取值是由数字构成的字符串

当前工作目录的绝对路径名,该变量的取值随cd命令的使用而变化

主提示符,在root用户缺省的主提示符是“#”,普通用户缺省是“$”

在shell接收用户输入命令的过程中,如果用户在输入行的末尾输入“”然后回车,或

者当用户按回车键时shell判断出用户输入的命令没有结束时,显示这个辅助提示符,提

示用户继续输入命令的其余部分,缺省的辅助提示符是“>”

(3)位置变量

位置参数是一种在调用shell程序的命令行中按照各自的位置决定的变量,是在程序名之后

输入的参数。位置参数之间用空格分隔,shell取第一个位置参数替换程序文件中的$1,第

二个替换$2,依次类推。$0是一个特殊的变量,它的内容是当前这个shell程序的文件名即

脚本名。

每个访问参数前要加&符号,第一个参数为0,表示预留保存实际脚本名字。

比如向脚本传送 I love you

$0 &1 &2 &3

脚本名字 I love you

例子:

$ vi findfile

#!/bin/sh

find / -name $1 -print

$ chmod a+x findfile

$ ./findfile /etc/passwd

特定变量参数

参数

$#

$*

$$

$!

$0

$@

$?

含义

传递到脚本的参数个数

所有位置参数的内容

脚本运行的当前进程ID号

后台运行的最后一进程的进程ID号

当前执行的进程名

与$#相同,但在使用时要加引号

命令执行后返回的状态 一般为 0

1.2 shell输入和输出

在shell脚本中,可以用几种不同的方式读入数据:可以使用标准输入—缺省为键盘,或者

指定一个文件作为输入。对于输出也是一样:如果不指定某个文件作为输出,标准输出总是

和终端屏幕相关联。

(1)echo

使用echo命令可以显示文本或者把字符串输入到文件。

$ echo string

c 不换行;t 跳格;n 换行;

-n选项禁止echo命令输出后换行,-e使转义符生效。

(2)read

Read语句从键盘或文件的某一行文本中读入信息,并将其付给一个变量,空格作为分隔符。

(3)cat

cat是一个简单而通用的命令,可以用它来显示文件内容,创建文件,还可以用它来显示控

制字符。

例子:

$ export NAME=hongdy

$ echo $NAME

hongdy

在使用cat命令时要注意,它不会在文件分页符处停下来;它会一下显示完整个文件。如果

希望每次显示一页,可以使用more命令或把cat命令的输出通过管道传递到另外一个具有

分页功能的命令中,比如:$ cat myfile | more

如果希望创建一个新文件,并向其中输入内容,cat命令把标准输出重定向到该文件中,标

准输入是键盘,输入完毕按ctrl+D结束输入。

cat > myfile

hongdy // 输入的内容,然后回车

ctrl+d // 结束输入返回

(4)pipe

可以通过管道把一个命令的输出传递给另一个命令作为输入,管道用竖杠 | 表示。

管道一般形式为:命令1 | 命令2

比如:$ ls | grep *.txt 在ls结果中搜索txt文件

(5)tee

tee命令作用可以用字母T来形象地表示。它把输出的一个副本输送到标准输出,另一个副

本拷贝到相应的文件中。

tee命令的一般形式:tee –a files -a 表示追加到文件末尾

比如:$ ls | tee result 将ls结果显示到标准输出,同时拷贝到文件中。

(6)重定向

标准输入是文件描述符0;标准输出是文件描述符1;标准错误是文件描述符2

$ command 1>filename // 把标准输出重定向到一个文件中

$ command > filename 2>&1 // 把标准输入和标准错误一起重定向到一个文件中

$ command < filename // 命令以filename文

件作为标准输入

例子:

$ grep “hello” * > result 2>&1

gerp 的结果将标准错误重定向到标准输出。

1.3 后台执行命令

使某些进程在后台运行,也就是说不在终端屏幕上运行。后台执行命令有以下四种:

命令

cron

含义

系统调度进程,使用它在每天的非高峰负荷时间段运行作业,或在一周或一月中的不同

时段运行

at

&

nohup

at命令,在一个特定的时间运行一些特殊的作业,或在非负荷高峰时间段或高峰负荷时

间段运行

使用它在后台运行一个占用时间不长的进程

使用它在后台运行一个命令,即使在用户退出时也不受影响

(1)cron

cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron 是

Linux的内置服务,但它不自动启动,可以用以下的方法启动、关闭这个服务:

# /sbin/service crond start //启动服务

# /sbin/service crond stop //关闭服务

# /sbin/service crond restart //重启服务

# /sbin/service crond reload //重新载入配置

也可以将这个服务在系统启动的时候自动启动。

比如:在/etc/rc.d/这个脚本的末尾加上 /sbin/service crond start

crontab命令

crontab命令的一般形式为:crontab [-u user] -e -l –r

-u 用户名;-e 编辑crontab文件;-l 列出crontab文件中的内容;-r 删除crontab文件。

cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明:

# crontab -u // 设定某个用户的cron服务,一般root用户在执行此命令的时候需要此

参数

# crontab -l // 列出某个用户cron服务的详细内容

# crontab -r // 删除某个用户的cron服务

# crontab -e // 编辑某个用户的cron服务

例子:

root查看自己的cron设置:# crontab -u root -l

root删除hongdy用户的cron设置: # crontab -u hongdy -r

在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root –e ,进入vi编

辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/

这个格式的前一部分是对时间的设定,后面一部分是要执行的命令,如果要执行的命令太多,

可以把这些命令写到一个脚本文件,然后在这里直接调用这个脚本文件,调用的时候写出命

令的完整路径。

时间的设定我们有一定的约定,前面五个*号代表五个数字,数字的取值范围和含义如下:

分钟(0-59);小時(0-23);日期(1-31);月份(1-12);星期(0-6)//0代表星期天

除了数字还有几个特殊的符号就是"*"、"/"和"-"、",",*代表所有的取值范围内的数字,/代

表每的意思,"*/5"表示每5个单位,"-"代表从某个数字到某个数字, ","分开几个离散的数字。

例子:

(1) 每天早上6点

0 6 * * * echo "Good morning." >> /tmp/

(2) 每两个小时

0 */2 * * * echo "Have a rest" >> /tmp/

(3) 晚上11点到早上8点之间每两个小时,早上八点

0 23-7/2,8 * * * echo "Have a good dream" >> /tmp/

(4) 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点

0 11 4 * 1-3 echo "Have a rest" >> /tmp/

(5) 1月1日早上4点

0 4 1 1 * echo "Have a rest" >> /tmp/

每次编辑完某个用户的cron设置后,cron自动在/var/spool/cron下生成一个与此用户同名的

文件,此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用

crontab -e 来编辑。cron启动后每过一份钟读一次这个文件,检查是否要执行里面的命令。

因此此文件修改后不需要重新启动cron服务。

(2)at命令

at命令允许用户向cron守护进程提交作业,使其在稍后的时间运行。这里稍后的时间可能

是指10 min以后,也可能是指几天以后。如果你希望在一个月或更长的时间以后运行,最

好还是使用crontab文件。一旦一个作业被提交,a t命令将会保留所有当前的环境变量。

At命令

at命令的基本形式为: at [-f script] [-m -l -r] [time] [date]

其中:

-f script 是所要提交的脚本或命令。

-m 作业完成后给用户发邮件。

-l 列出当前所有等待运行的作业。

-r 清除作业。为了清除某个作业,还要提供相应的作业标识(ID)。

time at命令的时间格式非常灵活;可以是H、HH . HHMM、HH:MM或H:M,其中H和M

分别是小时和分钟。还可以使用a . m .或p . m .。

date 日期格式可以是月份数或日期数,而且at命令还能够识别诸如today之类的词。

使用at命令提交作业有几种不同的形式:可以通过命令行方式,也可以使用a t命令提示符。

如果你想提交若干行的命令,可以在at命令后面跟上日期/时间并回车。然后就进入了at命

令提示符,这时只需逐条输入相应的命令,然后按 退出。

例子:

提交作业

# at 10:50

at> find / -name “passwd” –print

at>

其中就是

列出提交的作业

# at –l

清除作业

$atrm [job no]或 at -r [job no]

要清除某个作业,首先要执行at -l命令,以获取相应的作业标识,然后对该作业标识使用

at -r 命令,清除该作业。

(3)&命令

当在前台运行某个作业时,终端被该作业占据;而在后台运行作业时,它不会占据终端。

可以使用&命令把作业放到后台执行。

该命令的一般形式为:命令 &

(4)nohup命令

如果正在运行一个进程,而且觉得在退出帐户时该进程还不会结束,那么可以使用nohup

命令。该命令可以在你退出帐户之后继续运行相应的进程。Nohup就是不挂起的意思( no

hang up)。

nohup命令的一般形式为:nohup command &

1.4 正则表达式

使用shell时,从一个文件中抽取多于一个字符串将会很麻烦。例如:在一个文本中抽取一

个词,它的头两个字符是大写的,后面紧跟四个数字。如果不使用某种正则表达式,在shell

中将不能实现这个操作。

基本元字符集及其含义

元字符

^

$

*

[]

含义

只匹配行首

只匹配行尾

一个单字符后紧跟*,匹配0个或多个此单字符

匹配[]内字符。可以是一个单字符,也可以是字符序列。可以使用-表示[]内字符序列

范围,如用[1-5 ]代替[12345]

用来屏蔽一个元字符的特殊含义。因为shell中一些元字符有特殊含义。可以使其失

去应有意义匹配任意单字符

pattern{n}

pattern{n,}m

pattern{n,m}

只用来匹配前面pattern出现次数,n为次数

含义同上,但次数最少为n

含义同上,但pattern出现次数在n与m之间

使用句点匹配单字符

句点“.”可以匹配任意单字符。例如:如果要匹配一个字符串,以beg开头,中间夹一个

任意字符,那么可以表示为beg.n,“.”可以匹配字符串头,也可以是中间任意字符。

在行首以^匹配字符串或字符序列

^只允许在一行的开始匹配字符或单词。

在行尾以$匹配字符串或字符

可以说$与^正相反,它在行尾匹配字符串或字符, $符号放在匹配单词后。假定要匹配以单

词txt结尾的所有行txt$

使用*匹配字符串中的单字符或其重复序列

使用此特殊字符匹配任意字符或字符串的重复多次表达式。例如:compu*t将匹配字符u一

次或多次。

使用屏蔽一个特殊字符的含义

有时需要查找一些字符或字符串,而它们包含了系统指定为特殊字符的一个字符。

什么是特殊字符?一般意义上讲,下列字符可以认为是特殊字符: $ . „ “” [ ] ^ | () + ?

假定要匹配包含字符“.”的各行而“.”代表匹配任意单字符的特殊字符,因此需要屏蔽其

含义。操作如下: . 不认为反斜杠后面的字符是特殊字符,而是一个普通字符即句点。

如果要在正则表达式中匹配以*.txt结尾的所有文件,可做如下操作: *.txt 即可屏蔽字符

*的特定含义。

使用{}匹配模式结果出现的次数

使用*可匹配所有匹配结果任意次,但如果只要指定次数,就应使用 { },此模式有三种形

式,即:

pattern{n} 匹配模式出现n次。

pattern{n,} 匹配模式出现最少n次。

pattern{n,m} 匹配模式出现n到m次之间,n , m为0 - 2 5 5中任意整数。

1.5 grep

全局正则表达式版本grep允许对文本文件进行模式查找,可以和正则表达式一起使用。

grep一般格式:grep [选项] 基本正则表达式 [文件]

基本正则表达式可为字符串。在grep命令中输入字符串参数时,最好将其用双引号括起来。

有两个原因,一是以防被误解为shell命令,二是可以用来查找多个单词组成的字符串。

常用的grep选项:

选项

-c

-i

-h

-l

-n

-s

-v

-R

含义

只输出匹配行的计数

不区分大小写

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

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

显示匹配行及行号

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

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

递归进入子目录

缺省情况下, grep是大小写敏感的,如要查询大小写不敏感字符串,必须使用-i开关。

精确匹配:每个匹配模式中抽取字符串后有一个键;使用grep抽取精确匹配的一种更

有效方式是在抽取字符串后加>。

使用正则表达式使模式匹配加入一些规则,因此可以在抽取信息中加入更多选择。使用正则

表达式时最好用单引号括起来,这样可以防止grep中使用的专有模式与一些shell命令的特

殊方式相混淆。

例子:

# grep –R –n –s “hongdy” /etc

查找/etc目录下所有包含hongdy的文件。-R表示递归查找etc下的所有目录;-n 表示显示

匹配行及行号;-s 表示不显示不存在或无匹配文件的错误信息。

1.6 tr

tr用来从标准输入中通过替换或删除操作进行字符转换,主要用于删除文件中控制字符或进

行字符转换。

使用tr时要转换两个字符串:字符串1用于查询,字符串2用于处理各种转换。tr刚执行时,

字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。

tr命令的一般格式:tr –c –d –s [ “string_to_translate_from” ] [ “string2_translate_to ] file

-c 用字符串1中字符集的补集替换此字符集

-d 删除字符串1中所有的输入字符

-s 输出有重复出现的字符序列,只保留第一个。

(1)删除重复出现的字符

$ tr –s “[a-z]” < file 去除文件file中所有重复字母

(2)删除空行

使用-s,换行的八进制表示为012 或使用换行速记方式 n。

$ tr –s “[012]” < // 使用八进制方式

$ tr –s [“n”] < // 使用转义字符

(3)大小写字母转换

$ echo “CHINA” | tr “[A-Z]” “[a-z]” // 转换成小写字母

$ echo “china” | tr “[a-z] “ “[A-Z]” // 转换成大写字母

$ cat file1 | tr “[A-Z]” “[a-z]” > file2 // 将文件file1大写转换成小写并输出至文件

file2

(4)删除指定字符

结合使用- c和- s选项。

$ tr –cs “[A-Z][a-z]” “[012*]” < file // 删除文件中所有数字,只保留字母。

(5)转换控制字符

tr的第一个功能就是转换控制字符,特别是从dos向UNIX转换。

使用 cat –v 显示控制字符。

$ cat –v

Zhou ^^^^^^12^M

Xu^^^^^^50^M

Hong^^^^100^M

^Z

„^^^^^^‟ 是tab键。每一行以Ctrl-M结尾,文件结尾Ctrl-Z。

查看ASCII表,^的八进制代码是136,^M是015,tab键是01,^Z是032

$ tr –s “[136]” “[011*]” <

$ tr –s “[015032]” [“n”] <

1.7 sed

1.7.1 sed概述

sed 是一种在线编辑器,它一次处理一行内容。处理时把当前处理的行存储在临时缓冲区中,

称为模式空间(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲

区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,

除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操

作;编写转换程序等。

可以通过定址来定位你所希望编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以

这两行为起止的行的范围,如1,3表示1、2、3行,美元符号$表示最后一行。范围可以通过

数据,正则表达式或者二者结合的方式确定 。在sed语句,正则表达式必须封闭在//中间。

在sed地址管理中默认是对全局进行操作,地址可以分为行地址和模式地址。如1,10d 12d

10,$d 表示行地址,如/^$/d 表示模式地址。用户在进行操作时,可以对行地址和模式地址

结合进行操作。

1.7.2 Sed命令

调用sed命令有两种形式:

sed [options] 'command' file(s)

sed [options] -f scriptfile file(s)

选项

-e command, --expression='#'" style=""> 允许多台编辑。

-h, --help 打印帮助,并显示bug列表的地址。

-n, --quiet, --silent 取消默认输出。

-f, --filer=script-fil 引导sed脚本文件名。

-V, --version 打印版本和版权信息。

(1)替换命令

语法格式:sed „s/old/new/flags‟ file

文件file中内容old用new替换。

Flags:g表示对全局进行替换;w file:表示匹配行的内容写到另一个文件中。

例如:

$ sed „s/unix/Linux/g‟ file 文件file中所有内容unix都用Linux替换

$ sed „s/unix/Linux/w 11‟ file文件file中所有内容unix都用Linux替换并将结果写入11

(2)删除命令

语法格式:sed „[address]d‟ file

删除文件file中address表达的内容

例如:

$ sed „/^.aa/d‟ file 删除文件file中以.aa开头的内容

$ sed „/^$/d‟ file 删除文件file中空行的内容

$ sed „10d‟ file 删除文件file中第10行的内容。

(3)追加命令

语法格式:sed „[address]atext‟ file

文件file中address表达的行后面添加text内容

例如:

$ sed '10aabcd' file 在文件file中的第10行后面追加一行abcd字符

$ sed '/unix/aabcd' file 在文件file中所有出现unix字符的行后面追加一行abcd字符

$ sed '/unix/aabcdndcba' file 在文件file中出现unix字符行后面追加两行字符:abcd和dcba。

(4)插入命令

语法格式:sed „[address]itext‟ file

文件file中address表达内容行前面插入text内容。

例如:$ sed '/unix/iabcd´ file 在文件file中unix行前面插入abcd字符

(5)更改命令

语法格式:sed „[address]ctext‟ file

文件file中address表达内容的行用text代替。

例如:$ sed '1caaaa' file 将文件file中第一行的内容更改为aaaa.

(6)打印行号

语法格式:sed „[address]=‟ file

打印 文件file中address表达内容的行号

例如:

$ sed '/unix/=' file 打印文件file中包含unix字符的行号。不包含unix字符的行不打印行号。

(7)读写文件

语法格式:sed „[address]r file1‟ file 文件file中address表达的内容后插入文件file1的内容

语法格式:sed „[address]w file1‟ file 文件file中address表达的内容写入文件file2中

例如:

$ sed '/unix/r 11‟ file 在文件file中unix字符的后面读入11文件的内容

$ sed '2r 11' file 在文件file的第2行后面读入11文件的内容

$ sed '2,5w 22' file 将文件file中第2行到第5行的内容写到22文件中去。

1.8 awk

1.8.1 awk概述

awk是一种样式扫描与处理工具,与sed和grep很相似,但其功能却大大强于sed和grep,

它几乎可以完成grep和sed所能完成的全部工作,同时它还可以可以进行样式装入、流控

制、数学运算符、进程控制语句甚至于内置的变量和函数。

awk是以三个创立者的名字(Aho、Peter Weinberg和Brain Kernighan)的缩写命名的,awk

拥有自己的语言:awk程序设计语言。awk语言的最基本功能是在文件或字符串中基于指定

规则浏览和抽取信息。awk抽取信息后才能进行其他文本操作。

1.8.2 Awk调用

有三种方式可以调用awk

(1) awk命令行:awk [-F field-separator] „commands‟ input-file(s)

[-F 域分隔符]是可选的,awk使用空格作为缺省的分隔符;commands是真正的awk命令;

input-files是一个或多个输入文件。

(2)将所有的awk命令插入一个脚本文件并以 #!/bin/awk -f 作为首行,给予该脚本可执行

权限,然后在shell下通过键入该脚本的脚本名调用之。

(3) 将所有的awk命令插入一个单独脚本文件,然后使用: awk -f awk-script-file input_file(s)

-f选项指明文件awk-script-file中的awk脚本,input-files是一个或多个输入文件。

awk命令的一般形式

awk ' BEGIN { actions }

awk_pattern1 { actions }

............

awk_patternN { actions }

awk END { actions }

其中 BEGIN { actions } 和 END { actions } 是可选的。

awk脚本文件

#!/bin/awk -f

BEGIN { print "this is the begin of awk script" }

{ print $1, $2, $3 }

END { print "this is the end of awk script" }

第一行是!/bin/awk -f。这很重要,没有它自包含脚本将不能执行。这一行告之脚本系统中awk

的位置。通过将命令分开,脚本可读性提高,还可以在命令之间加入注释,使用“#”作为注

释符,它使“#”到行尾的内容成为注释。

域和记录

awk执行时,其浏览域标记为$1、$2 . . . $n,这种方法称为域标识。使用这些域标识将更容

易对域进行进一步处理。使用$ 1 , $ 3表示参照第1和第3域,注意这里用逗号做域分隔。如

果希望打印一个有5个域的记录的所有域,不必指明$ 1 , $ 2 , $ 3 , $ 4 , $ 5,可使用$ 0,意即

所有域。

例子:

$ awk -F ":" '{print $1, $3, $6}' /etc/passwd 打印passwd文件的用户名、用户ID和用户目录

$ awk '/hongdy/{print}' /etc/passwd 显示文本文件passwd含有字符串hongdy的所有行。

流程控制结构

(1)if (condition) {then-body} [else {else-body}]

(2)while (condition) {body}

(3)do {body} while (condition)

(4)for (initialization; condition; increment) {body}

其中condition一般为布尔表达式,body和else-body是awk语句块。

1.8.3 awk变量

在awk脚本中的表达式中要经常使用变量。不要给变量加双引号,因为awk将视之为字符

串。awk的变量基本可以分为两类:awk内部变量和自动以变量。

1.8.3.1 awk内部变量

awk的内部变量用于存储awk运行时的各种参数,这些内部变量又可以分为:

(1)自动内部变量:这些变量的值会随着awk程序的运行而动态的变化,在awk_script中

改变这些变量的值是没有意义的(即不应该被赋值)。

常用的自动内部变量

变量

NF

NR

FNR

ARG

C

FILE

NAM

E

ARGI

ND

当前被处理的文件在数组ARGV内的索引

当前输入文件的文件名

说明

当前输入字段的字段数

当前输入文件中已经被awk读取过的记录行的数目

已经被awk读取过的记录行的总数目。只有一个输入文件时FNR和NR相等

命令行参数个数

例子:

$ awk „{ print “filename=” FILENAME, “count=” NF}‟ 11 假设文件11内容为

123 abc。

Filename=11, count=2

(2)字段变量($0 $1 $2 $3 ...)

当awk把当前输入记录分段时,会对这些字段变量赋值。在awk运行过程中字段变量的值

是动态变化的。可以创建新的输出字段,比如当前输入记录被分割为8个字段,这时可以通

过对变量 $9 (或$9之后的字段变量)赋值而增加输出字段,NR的值也将随之变化。

字段变量支持变量名替换。

例子:

$ pwd | awk -F/ '{print $NF}' 打印输入记录的最后一个字段

如果当前目录为/home/hongdy/linux , awd 以/ 为分隔符,有三个字段,输入的最后一个字段

为linux

$ awk '{x=2;print $x}' 11 打印输入记录的第2个字段

如果文件11的内容为zhou xu hong, 有三个字段,第二个字段即为xu

(3)其它内部变量

可以修改这些变量。常见的有:

变量

FS

OFS

说明

输入记录的字段分隔符(默认是空格和制表符)

输出记录的字段分隔符(默认是空格)

OFMT

RS

ORS

ARGV

ENVIRON

数字的输出格式(默认是 %.6g)

输入记录间的分隔符(默认是NEWLINE)

输出记录间的分隔符(默认是NEWLINE)

命令行参数数组

存储系统当前环境变量值的数组

例如:

$ cat /etc/passwd | awk 'BEGIN { FS=":" } {print "User name: "$1,"UID: "$3}'

文件/etc/passwd内容类似于 hongdy:x:501:501:hongdy:/home/hongdy:/bin/sh,以:为分隔符,

打印用户名和用户ID。

1.8.3.2 自定义变量

(1)定义变量varname=value (自定义变量不需声明,赋值语句同时完成变量定义和初始化)

(2)表达式中出现不带双引号的字符串都被视为变量,如果未赋值默认值为0或空字符串。

1.8.4 Awk函数

可以在awk_script的任何地方使用awk函数。awk函数可以分为内置函数和自定义函数。

1.8.4.1 awk内置函数

(1)常见awk内置数值函数

函数名

int(x)

sqrt(x)

exp(x)

log(x)

sin(x)

cos(x)

rand ()

srand(x)

说明

求出x 的整数部份,朝向0 的方向做舍去。eg: int(3.9)是3

求出x 正的平方根值。eg: sqrt(4)=2

求出x 的次方。eg: exp(2) 即是求e*e 。

求出x 的自然对数。

求出x 的sine 值,x 是弪度量。

求出x 的cosine 值,x 是弪度量。

得到一个随机数(平均分布在0和1之间)。

设定产生随机数的seed为x。

例子:$ awk '{ print log($1)}' 12 假设文件12的内容第一个域值是2,打印log2的值

(2)常见awk内置字符串函数

函数名

index(in, find)

length(s)

match(s,r)

sprintf(fmt,exp1,...)

sub(p, r,t)

substr(str, st, len)

说明

返回字符串in中字符串find第一次出现的位置(索引从1开始),如果在字串in中找不

到字符串find,则返回值为0。

求出字符串s的字符个数。eg: length("abcde") 是5。

r在字符串s的第一次出现的位置,如果s不包含r,则返回值0。

返回模式字符串: 和printf类似印出

在字符串t中寻找符合模式字符串p的最靠前最长的位置,并以字符串r代替最前的

p。

传回str的子字符串,其长度为len字符,从str的第st个位置开始。如果len没有出

现,则传回的子字符串是从第st个位置开始至结束。

split(s,a,fs)

tolower(str)

toupper(str)

在分隔符fs为分隔符将字符串s分隔成一个awk数组a,并返回a的下标数

将字符串str的大写字母改为小写字母

将字符串string 的小写字母改为大写字母

例子:$ echo "abcdefg" | awk '{print length($0)}' 打印字符串“abcdefg”的长度

(3)常见awk内置系统函数

函数名

close(filename)

system(command)

说明

将输入或输出的文件filename 关闭

此函数允许调用操作系统的指令,执行完后将回到awk程序

1.8.4.2 自定义函数

复杂的awk常常可以使用自己定义的函数来简化。调用自定义的函数与调用内置函数的方

法一样。

自定义函数定义的格式:自定义函数可以在awk程序的任何地方定义。

function fun_name (parameter_list) { // parameter_list是以逗号分隔的参数列表

body-of-function // 函数体,是awk语句块

}

例子:

$ awk '{ print "sum =" SquareSum($1,$2) } function SquareSum(x,y) { sum=x*x+y*y ; return

sum } ' 11

自定义了一个平方和的函数,从文件11中取出两个数,打印他们的平方和。

或者写到脚本文件里

$ vi awk_fun

#!/bin/awk -f

function SquareSum(x, y){ sum = x*x + y*y; return sum;}

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

$ chmod a+x awk_fun

$ ./awk_fun 11

sum=13 假设文件11的内容是2 3,平方和是13。

1.8.4.3 Awk输出函数printf

awk提供函数printf,拥有几种不同的格式化输出功能,每一种printf函数都以一个%符号开

始,以一个决定转换的字符结束。printf函数基本语法是printf([格式控制符],参数)。

例子:

$ awk '{ printf("%d %sn", $1, $2) }' 11

123 abc 假设文件11的内容是数字123 和字符串abc,使用printf

打印整型数和字符串。

1.9 引号

符号

双引号

单引号

反引号

反斜线

含义

可以引用除字符$ 、 外的任意字符或字符串

与双引号类似,不同的是shell会忽略任何引用值

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

屏蔽特殊含义 & * + $ ` “ | ?

1.10 命令执行顺序

在执行某个命令的时候,有时需要依赖于前一个命令是否执行成功。比如:往某个文件夹写

入文件,要先判断那个文件夹是否存在,否则无法写入文件。

如果希望在成功地执行一个命令之后再执行另一个命令,或者在一个命令失败后再执行另一

个命令,&&和 | | 可以完成这样的功能。相应的命令可以是系统命令或shell脚本。Shell

还提供了在当前shell或子shell中执行一组命令的方法,即使用()和{ }。

(1)使用 &&

使用&&的一般格式:命令1 && 命令2

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

(2)使用 ||

使用 || 的一般格式: 命令1 || 命令2

|| 左边的命令未执行成功,|| 右边的命令才能够执行。

(3)用 () 和 {} 将命令结合在一起

为了在shell中执行一组命令,用命令分隔符隔开命令,并把所有的命令用()或{}括起来。

() 的一般形式: (命令1; 命令2;….)

{} 的一般形式: {命令1; 命令2; . . }

如果使用{}代替(),那么相应的命令将在子shell而不是当前shell中作为一个整体被执行。

例子:

$ [ -d test ] && rmkdir test // 如果当前目录下的test是个目录,则删

除这个目录

$ [ -f test ] || touch test // 如果test不是一个正规文件,则创建

一个文件

1.11 控制流结构

(1)if 语句

if then else 语句的一般格式:

if 条件1

then 命令1

elif 条件2

then 命令2

else 命令3

fi

使用if语句时,必须将then部分放在新行,否则会产生错误。如果不分行,必须使用命令

分隔符。

if 条件; then

命令

fi

例子:

vi

#!/bin/sh

echo "Please input your name?"

read NAME

echo "Please input your sex?"

read SEX

if [ $SEX = "male" ] ; then

echo "Name: $NAME Sex: male"

elif [ $SEX = "female" ]; then

echo "Name: $NAME Sex: female"

else

echo "Name: $NAME Sex: unkonwn"

fi

程序提示用户输入姓名和性别,然后判断性别并打印结果。

(2)case 语句

case 语句的一般格式:

case 值 in

模式1}

命令1

;;

模式2}

命令2

;;

esac

例子:

$ vi

#!/bin/sh

echo -n "Enter a number from 1 to 3:"

read NUM

case $NUM in

1) echo "your select 1"

;;

2) echo "your select 2"

;;

3) echo "your select 3"

;;

*) echo "your select out 1-3"

;;

esac

程序提示用户输入选择,然后打印用户的选择。

(3)for循环

For循环的一般格式:

for 变量名 in 列表

do

命令1

命令2

done

for循环不使用in列表选项,接受命令行位置参数作为参数,查看特定参数$@ 或 $*,已从

命令行中取得参数

for param in "$@" or for param in "$*"

例子:

vi

for loop in 1 2 3 4 5

do

echo $loop

done

(4)while循环

While循环用于不断执行一系列命令,也用于从文件中读取数据。

While循环的一般格式:

while 命令

do

命令1

命令2

...

done

例子:

$ vi

#!/bin/sh

COUNTER=0

while [ $COUNTER -lt 5 ]

do

COUNTER=`expr $COUNTER + 1`

echo $COUNTER

done

COUNTER初始化为0,然后每次加1并打印,直到COUNTER小于5。

1.12 条件测试

1.12.1 测试文件状态

test一般有两种格式:test condition 或 [condition]

文件状态有:

(1)-d目录;(2)-s非空;(3)-f正规文件;(4)-L符号连接;

(5)-r可读;(6)-w可写;(7)-x可执行

例子:

$ ls –al

-rw-r-r--

$ test -w 或 [ -w ]

$ echo $?

测试时可使用逻辑操作符

(1)-a逻辑与: 操作符两边均为真,结果为真,否则为假。

(2)-o逻辑或: 操作符两边一边为真,结果为真,否则为假。

例子:

$ [ -w file1 -a –w file2 ]

$ echo $?

1.12.2 字符串测试

字符串测试的一般格式:[ string1 string_operation string2 ]

字符串操作符有:

(1)= 两个字符串相等; (2)!= 两个字符串不相等

(3)-z 空串 (4)-n 非空串

例子:

$ [ -z $EDITOR ] 测试环境变量EDITOR是否为空

$ echo $?

1.12.3 数值测试

数值测试的一般格式:["number" numeric_operator "number" ]

数值操作符有:

(1)-eq数值相等; (2)-ne数值不相等;

(3)-gt第一个数大于第二个数; (4)-lt第一个数小于第二个数;

(5)-le第一个数小于等于第二个数; (6)-ge第一个数大于等于第二个数

例子:

$ [ 31 -eq 31 ]

$ echo $?

expr用法

expr命令一般用于整数值,但也可用于字符串。

expr的一般格式:expr argument operator argument

例子:

$ expr 10 + 10 数值前后要有空格

$ expr 30 / 3

$ expr 20 * 3 // 使用乘号时必须用反斜线屏蔽其特定含义

expr在循环中用于增量计算。首先循环初始化为0,然后循环值加1,反引号的用法意即替代

命令。

最基本的一种是从(expr)命令接受输出并将之放入循环变量。

例子:

$ LOOP = 0 等于号前后不能

有空格

$ LOOP = `expr $LOOP + 1` 加号前后要有空格

$ echo $LOOP 打印LOOP值

1

1.13 shell函数

函数由两部分组成: 函数标题 和 函数体。

标题是函数名,标题名应该唯一;函数体是函数内的命令集合。

定义函数的格式为:

函数名()

{

命令1

….

}

定义函数也可在函数名前加function。所有函数在使用前必须定义,一般将函数放在脚本

开始部分。调用函数仅使用其函数名即可。

例子:

vi

my_date ()

{

echo “Today‟s date is `date` “

}

echo “now execute function my_date”

my_date

$ sh

Now execute function hello

Today's date is Wed Feb 27 22:48:21 CST 2008

定义一个my_date函数,主要功能是打印当前的日期时间,然后执行这个函数。

定位shell函数:.

使用shell函数:function_name

删除shell函数:unset function_name

例如:

$ . 定位shell函数

$ set | grep my_date 在set环境变量里查看函数my_date是否被载入

my_date()

$ my_date 使用shell函数

Today's date is Wed Feb 27 22:48:21 CST 2008

$ unset my_date 删除shell函数

$ set | grep my_date 在set环境变量里查看函数my_date是否存在

向函数传递参数

向函数传递参数就像在一般脚本中使用特殊变量$ 1 , $ 2 . . . $ 9一样,函数取得所传参数后,

将原始参数传回shell脚本,因此最好先在函数内重新设置变量保存所传的参数。函数调用

参数的转换以下划线开始,后加变量名,如_name.

从调用函数中返回

当函数完成处理或希望函数基于某一测试语句返回时,可做两种处理:

1) 让函数正常执行到函数末尾,然后返回脚本中调用函数的控制部分。

2) 使用return返回脚本中函数调用的下一条语句,可以带返回值,0为无错误,1为有错误。

可以直接在脚本调用函数语句的后面使用最后状态命令($?)来测试函数的返回值。

本文标签: 命令文件使用字符串