Shell 编程
Shell 编程
曙光信息产业有限公司
技术支持中心
Index
• The shell of Linux
• Bourne Shell Programming
• find.and.regular.expression
• text manipulation
Shell 编程 2
The shell of Linux
• Bourne shell (sh),
• C shell (csh),
• Korn shell (ksh),
• TC shell (tcsh),
• Bourne Again shell (bash)
Shell 编程 3
Difference between programming and
scripting languages
Shell 编程 4
The first bash program
• We must know how to use a text editor. There are two major text
editors in Linux:
– vi, emacs (or xemacs).
• So fire up a text editor; for example:
– $ vi &
and type the following inside it:
– #!/bin/bash
echo “Hello World”
• The first line tells Linux to use the bash interpreter to run this script.
We call it hello.sh. Then, make the script executable:
– $ chmod 700 hello.sh
– $ ls –l
-rwx------ hello.sh
Shell 编程 5
The first bash program
• To execute the program:
– $ hello.sh
-bash: hello.sh: command not found
The home directory (where the command hello.sh is located)
is not in the variable PATH
– echo $PATH
:bin:/usr/bin:…
We must specify the path of hello.sh
– $/home/srinaldi/Scripts/hello.sh
– $./hello.sh
Shell 编程 6
The second bash program
• We write a program that copies all files into a directory, and then deletes the
directory along with its contents. This can be done with the following
commands:
– $ mkdir trash
$ cp * trash
$ rm -rf trash
$ mkdir trash
• Instead of having to type all that interactively on the shell, write a shell
program instead:
– $ cat trash
#!/bin/bash
# this script deletes some files
cp * trash
rm -rf trash
mkdir trash
echo “Deleted all files!”
Shell 编程 7
• Bourne Shell Programming
Shell 编程 75
Bourne Shell Programming
• Certainly the most popular shell is “bash”. Bash
is the shell that will appear in the GNU operating
system. Bash is an sh-compatible shell that
incorporates useful features from the Korn shell
(ksh) and C shell (csh).
• bash is not only an excellent command line shell,
but a scripting language in itself. Shell scripting
allows us to use the shell's abilities and to
automate a lot of tasks that would otherwise
require a lot of commands.
Shell 编程 76
Borne Shell
Background
m Early Unix shell that was written by Steve
Bourne of AT&T Bell Lab.
m Basic shell provided with many commercial
versions of UNIX
m Many system shell scripts are written to run
under Bourne Shell
m A long and successful history
Shell 编程 77
Bourne Shell Programming
• Control structures
– if … then
– for … in
– while
– until
– case
– break and continue
Shell 编程 78
if … then
• Structure
if test-command
then
commands
fi
Example:
Shell 编程 79
test
• Command test is a built-in command
• Syntax
test expression
[ expression ]
– The test command evaluate an expression
– Returns a condition code indicating that the expression is
either true (0) or false (not 0)
• Argument
– Expression contains one or more criteria
• Logical AND operator to separate two criteria: -a
• Logical OR operator to separate two criteria: -o
• Negate any criterion: !
• Group criteria with parentheses
– Separate each element with a SPACE
Shell 编程 80
Test Criteria
Relop Description
-gt Greater than
-ge Greater than or equal to
-eq Equal to
-ne Not euqal to
-le Less than or equal to
-lt Less than
Shell 编程 81
Exercise
• Create a shell script to check there is at least one
parameter
– Something like this:
…
if test $# -eq 0
then
echo “ you must supply at least one
arguments”
exit 1
fi
…
Shell 编程 82
Test Criteria
• The test built-in options for files
Option Test Performed on file
-d filename Exists and is a directory file
…… ……
Shell 编程 83
Exercise
• Check weather or not the parameter is
a non-zero readable file name
– Continue with the previous script and add
something like
if [ -r “$filename” –a –s “$filename” ]
then
……
fi
Shell 编程 84
Test Criteria
• String testing
Criteria meaning
Shell 编程 85
Exercise
• Check users confirmation
– Frist, read user input
echo -n “Please confirm: [Yes | No] “
read user_input
– Then, compare it with standard answer ‘yes’
if [ “$user_input” = Yes ]
then
echo “Thanks for your confirmation!”
Fi
Shell 编程 86
if…then…else
• Structure
if test-command
then
commands
else
commands
fi
– You can use semicolon (;) ends a command the same way a
NEWLINE does.
if [ … ]; then
……
fi
Shell 编程 88
Debugging Shell Scripts
• Display each command before it runs the command
– Set the –x option for the current shell
• $set –x
– Use the –x to invoke the script
• $sh –x command arguments
– Add the set command at the top of the script
• set –x
• Then each command that the script executes is
preceded by a plus sign (+)
– Distinguish the output of trace from any output that the
script produces
• Turn off the debug with set +x
Shell 编程 89
for… in
• Structure
for loop-index in argument_list
do
commands
done
Example:
for file in *
do
if [ -d “$file” ]; then
echo $file
fi
done
Shell 编程 90
for
• Structure
for loop-index
do
commands
done
Example:
while [ “$number” –lt 10 ]
do
……
number=`expr $number + 1`
done
Shell 编程 92
until
• Structure
until test_command
do
commands
done
Example:
secretname=jenny
name=noname
until [ “$name” = “$secretname” ]
do
echo “ Your guess: \c”
read name
done
Shell 编程 93
break and continue
• Interrupt for, while or until loop
• The break statement
– transfer control to the statement AFTER the done
statement
– terminate execution of the loop
• The continue statement
– Transfer control to the statement TO the done
statement
– Skip the test statements for the current iteration
– Continues execution of the loop
Shell 编程 94
Example:
for index in 1 2 3 4 5 6 7 8 9 10
do
if [ $index –le 3 ]; then
echo continue
continue
fi
echo $index
if [ $index –ge 8 ]; then
echo “break”
break
fi
done
Shell 编程 95
case
• Structure
case test_string in
pattern-1 )
commands_1
;;
pattern-2 )
commands_2
;;
……
esac
• default case: catch all pattern
*)
Shell 编程 96
case
• Special characters used in patterns
Pattern Matches
Shell 编程 97
Example
#!/bin/sh
echo “\n Command MENU\n”
echo “ a. Current data and time”
echo “ b. Users currently logged in”
echo “ c. Name of the working directory\n”
echo “Enter a,b, or c: \c”
read answer
echo
case “$answer” in
a)
date
;;
b)
who
;;
c)
pwd
;;
*)
echo “There is no selection: $answer”
;;
esac Shell 编程 98
Built-in: exec
• Execute a command:
– Syntax: exec command argument
– Run a command without creating a new process
• Quick start
• Run a command in the environment of the original
process
• Exec does not return control to the original program
• Exec can be the used only with the last command that
you want to run in a script
• Example, run the following command in your current
shell, what will happen?
$exec who
Shell 编程 101
Built-in: exec
• Redirect standard output, input or error of a shell script from
within the script
• exec < infile
• exec > outfile 2> errfile
– Example:
sh-2.05b$ more redirect.sh
exec > /dev/tty
echo "this is a test of redirection"
Shell 编程 102
Catch a signal: builtin trap
• Built-in trap
– Syntax: trap ‘commands’ signal-numbers
– Shell executes the commands when it catches one of the
signals
– Then resumes executing the script where it left off.
• Just capture the signal, not doing anything with it
trap ‘ ‘ signal_number
– Often used to clean up temp files
– Signals
• SIGHUP 1 disconnect line
• SIGINT 2 control-c
• SIGKILL 9 kill with -9
• SIGTERM 15 default kill
• SIGSTP 24 control-z
• …
Shell 编程 103
Example
[ruihong@dafinn ~/cs3451]$ more inter
#!/bin/sh
trap 'echo PROGRAM INTERRUPTED' 2
while true
do
echo "programming running."
sleep 1
done
Shell 编程 104
A partial list of built-in
• bg, fg, jobs job control
• break, continue change the loop
• cd, pwd working directory
• echo, read display/read
• eval scan and evaluate the
command
• exec execute a program
• exit exit from current shell
• export, unset export/ remove a val or fun
• test compare arguments
Shell 编程 105
A partial list of builtin
• kill sends a signal to a process or job
• set sets flag or argument
• shift promotes each command line argument
• times displays total times for the current shell
and
• trap traps a signal
• type show whether unix command, build-in,
function
• umask file creation mask
• wait waits for a process to terminate.
• ulimit print the value of one or more resource
limits Shell 编程 106
functions
• A shell function is similar to a shell script
– It stores a series of commands for execution at a later time.
– The shell stores functions in the memory
– Shell executes a shell function in the same shell that called
it.
• Where to define
– In .profile
– In your script
– Or in command line
• Remove a function
– Use unset built-in
Shell 编程 107
functions
• Syntax
function_name()
{
commands
}
• Example:
sh-2.05b$ whoson()
>{
> date
> echo "users currently logged on"
> who
>}
sh-2.05b$ whoson
Tue Feb 1 23:28:44 EST 2005
users currently logged on
ruihong :0 Jan 31 08:46
ruihong pts/1 Jan 31 08:54 (:0.0)
ruihong pts/2 Jan 31 09:02 (:0.0)
Shell 编程 108
Example
sh-2.05b$ more .profile
setenv()
{
if [ $# -eq 2 ]
then
eval $1=$2
export $1
else
echo "usage: setenv NAME VALUE" 1>&2
fi
}
sh-2.05b$. .profile
sh-2.05b$ setenv T_LIBRARY /usr/local/t
sh-2.05b$ echo $T_LIBRARY
/usr/local/t
Shell 编程 109
Exercise
• Let’s look at some system scripts
– /etc/init.d/syslog
– /etc/init.d/crond
Shell 编程 110
Summary
• Shell is a programming language
• Programs written in this language are
called shell scripts.
– Variable
– Built-in
– Control structure
– Function
– Call utilities outside of shell
• find, grep, awk
Shell 编程 111
• Shell 中的find和正则表达式
Shell 编程 112
使用find和xargs
• find 命令选项
• 使用find 命令不同选项的例子
• 配合find 使用xargs的例子
• find命令的一般格式
– find pathname -options [-print -exec -ok]
– -print find 命令将匹配的文件输出到标准输出
– -exec find 命令对匹配到的文件执行该参数给出的shell命令,命
令格式为 ‘command’{} \
Shell 编程 113
find命令选项
• -name 按照文件名查找文件
• -perm 按照文件权限查找文件
• -prune 不在指定的目录中查找
• -user 按照文件属主查找
• -group 按照文件所属组进行查找
• -mtime -n +n 按照文件的更改时间来查找
• -nogroup 查找无有效所属组的文件
• -nouser 查找无效属主的文件
• -type 查找某一类型的文件
– b块设备文件
– d目录
– c字符设备
– p管道文件
– l符号链接
– f普通文件
Shell 编程 114
find命令选贤
• -depth 先查找当前目录中的文件再查找子目录
• -fstype 查找位于某一类型文件系统中的文件
• -mount 查找文件时不跨越mount点
• -follow 如果遇到符号链接,就跟踪至原文件
• -size n[c] 查找长度为n块的文件,c时为字节
长度
Shell 编程 115
find选项例子
• 使用name选项
– find . –name “*.txt” –print
• 使用perm选项
– find . –perm 755 –print
• 忽略某个目录
– find /apps –path“/apps/bin”-prune –o –print
• 使用user和nouser选项
– find ~ -user dave –print
– find /home –nouser
Shell 编程
-print 116
find 选项例子
• 按照更改时间查找文件
– find / -mtime -5 –print
• 使用type选项
– find /etc –type d -print
• 使用-size选项 (查找大于1M的文件)
– find . –size +1000000c –print
• 使用depth选项
– find / -name “a.out” –depth -print
Shell 编程 117
使用exec或者ok来执行shell命令
• exec后紧跟要执行的命令,然后是一对{},一个空格和一
个\
• find . –type f –exec ls –l {} \;
– 该例子中find匹配到了当前目录下所有的普通文件,并
在-exec选项中使用了ls –l 将它们列出
• find /logs –type f –mtime +5 –exec rm {} \;
– 在logs目录下查找更改时间在5日以前的文件并删除之
– 使用删除时,建议使用-ok选项而实现交互功能
Shell 编程 118
find命令实战
• find . -type f -perm 4755 –print
• find / -type f -size 0 -exec ls -l {} \;
• find /var/logs -type f -mtime +7 -exec
rm {} \;
• find /-name -group audit -print
• find . -type d -print -local -mount |sort
Shell 编程 119
xargs
• 解决find和-exec搭配使用时报参数列太长
的错误
• 使用xargs可以一次获取所有参数,也可以
分批获取参数
• find / -type –f –print | xargs file
• find /apps/audit -perm -7 -print | xargs
chmod o-w
Shell 编程 120
正则表达式
• 匹配行首和行尾
• 匹配数据集
• 只匹配字母和数字
• 匹配一定范围内的字符串集
Shell 编程 121
基本元字符集
Shell 编程 122
使用句点匹配单字符
• 句点可以匹配任意单字符
– beg.n 匹配以beg开头,中间夹一个任意字符
– ls –l中匹配一定的权限 …x..x..x
• drwxrwxrw- -no match
• -rw-rw-rw- -no match
• -rwxrwxr-x -match
– ….XC…. 前4个字符之后是XC,前4个后四个任意
• 1234XC9088 -match
• 4523XX9001 -no match
– “.”允许匹配ASCII集中任意字符
Shell 编程 123
在行首以^匹配字符串
• ^只允许在一行的开始匹配字符和单词
• ls –l匹配目录
– ^d
• drwxrwxrw- -match
• -rw-rw-rw- -no match
• ^comp..ing
– 行首为comp,后面紧跟2个任意字符,并以
ing结尾
Shell 编程 124
在行尾以$匹配字符串或字符
• $与^相反,在行尾匹配字符串
• 匹配以trouble结尾的所有行
– trouble$
• 匹配所有空行
– ^$
• 匹配只有一个字符的行
– ^.$
Shell 编程 125
使用*匹配字符串中的单字符或其重
复序列
• compu*t 将匹配字符u 0次或者多次
– computer
– computing
– compuuuuute
Shell 编程 126
使用\屏蔽特殊字符
• 特殊字符:
– $ . ’”* [ ] ^ | ( ) \ + ?
Shell 编程 127
使用[ ]匹配一个范围或集合
• 可用逗号将[ ]内不同字符串分开
• 使用-表示一个字符串范围
• 匹配任意一个数字
– [0123456789]
– [0-9]
• 匹配任意字母
– [a-zA-Z]
• 匹配任意字母或数字
– [a-zA-Z0-9]
Shell 编程 128
使用[ ]匹配一个范围或集合
• 匹配Computer和computer两个单词
– [Cc]omputer
• 匹配以字母o或u开头,后跟一个字符任意次,并以t结尾
的任意单词
– [ou].*t
• 匹配所有单词
– [A-Za-z]*
• 匹配任一非字母型字符
– [^a-zA-Z]
• 匹配任一非数字型字符
– [^0-9]
Shell 编程 129
使用\{\}匹配模式出现的次数
• pattern\{n\} 匹配模式出现n次
• pattern\{n,\} 匹配模式至少出现n次
• pattern\{n,m\} 匹配模式出现次数n到m之间
• A \{2\}B 匹配值为AAB
• A\{4,\}B 匹配A至少4次 AAAAB AAAAAAB
• [0-9]\{4\}XX[0-9]\{4\}
– 匹配数字出现4次,后跟代码XX,最后数字出现4次
– 4523XX9001
Shell 编程 130
经常使用的正则表达式
Shell 编程 131
经常使用的正则表达式
Shell 编程 132
• 文本过滤
Shell 编程 133
主要内容和学习要求
能够熟练运用 grep 命令
掌握 sed 流编辑器
学会使用 awk 编程
Shell 编程 134
grep 家族
grep 是 Linux 下使用最广泛的命令之一,其作用
是在一个或多个文件中查找某个字符模式所在的行,并
将结果输出到屏幕上。
grep 命令不会对输入文件进行任何修改或影响
egrep: 扩展 grep,支持基本及扩展的正则表达式。
pattern:可以是正则表达式(用单引号括起来)、
或字符串(加双引号)、或一个单词。
file1 file2 ... :文件名列表,作为 grep 命令的输入;grep 的输
入也可以来自标准输入或管道;
可以把匹配模式写入到一个文件中,每行写一个,然
后使用 -f 选项,将该匹配模式传递给 grep 命令
grep -f patternfile file1 file2 ...
Shell 编程 136
grep 常用选项
-c 只输出匹配的行的总数
-i 不区分大小写
-h 查询多个文件时,不显示文件名
-l 查询多个文件时,只输出包含匹配模式的文件的文
件名
-n 显示匹配的行及行号
-v 反向查找,即只显示不包含匹配模式的行
-s 不显示错误信息
grep "12" *
反向匹配
ps aux | grep "ssh" | grep –v "grep"
匹配空行
grep -n '^$' datafile
Shell 编程 139
grep 命令应用丼例
递归搜索目录中的所有文件:-r
grep -r "north" datafile ~/Teaching/linux/
关于某个字符连续出现次数的匹配
grep 'o\{2,\}' helloworld
Shell 编程 140
grep 命令应用丼例
其它
grep '^n' datafile
grep –c '\<[a-z].*n\>'Shell
datafile
编程 141
grep 与管道
ls –l | grep '^d'
其中 ACTION 可以是
read:把目录文件当作普通文件来读取
skip:目录将被忽略而跳过
recurse:递归的方式读取目录下的每一个文件,可以用选项 "-r" 代替
"-d recurse"
egrep 增加的元字符
+ 匹配一个或多个前一字符
? 匹配零个或一个前一字符
str1|str2 匹配 str1 或 str2
( ) 字符组
fgrep 命令
fgrep 的使用方法与 grep 类似,但对正则表达式中的任何元字符都不
做特殊处理。
sed 如何工作
sed 逐行处理文件(或输入),并将输出结果发送到屏幕。
即:sed 从输入(可以是文件或其它标准输入)中读取一行,将之拷贝到一个编
辑缓冲区,按指定的 sed 编辑命令进行处理,编辑完后将其发送到屏幕上,然后
把这行从编辑缓冲区中删除,读取下面一行。重复此过程直到全部处理结束。
-n:缺省情况下,sed 在将下一行读入缓冲区之前,自动输
出行缓冲区中的内容。此选项可以关闭自动输出。
-e:允许调用多条 sed 命令,如:
sed -e 'sed_cmd1' -e 'sed_cmd2' input_file
例:./sedfile2.sed -n datafile
Shell 编程 147
定位方式
sed_cmd 中 address 的定位方式
n 表示第 n 行
$ 表示最后一行
m,n 表示从第 m 行到第 n 行
/pattern/ 查询包含指定模式的行。如 /disk/、/[a-z]/
/pattern/,n 表示从包含指定模式的行 到 第 n 行
n,/pattern/ 表示从第 n 行 到 包含指定模式的行
/模式1/,/模式2/ 表示从包含模式1 到 包含模式2的行
反向选择,
!
如 m,n!的结果与 m,n 相反
Shell 编程 148
常用 sed 编辑命令
常用的 sed_edit_cmd
p :打印匹配行
sed -n '1,3p' datafile // ('1,3!p')
= :显示匹配行的行号
sed -n '/north/=' datafile
d :删除匹配的行
sed -n '/north/d' datafile
Shell 编程 149
常用 sed 编辑命令
a\ :在指定行后面追加一行或多行文本,并显示添加的
新内容,该命令主要用于 sed 脚本中。
sed -n '/eastern/a\newline1\
newline2\
newlineN' datafile
i\ :在指定行前插入一行或多行,并显示添加的新内容,
使用格式同 a\
c\ :用新文本替换指定的行,使用格式同 a\
l :显示指定行中所有字符,包括控制字符(非打印字符)
[address]s/old/new/[gpw]
address :如果省略,表示编辑所有的行。
g :全局替换
p :打印被修改后的行
w fname :将被替换后的行内容写到指定的文件中
& 符号用在替换字符串中时,代表Shell
被替换的字符串
编程 151
常用 sed 编辑命令
r :读文件,将另外一个文件中的内容附加到指定行后。
w :写文件,将指定行写入到另外一个文件中。
n :将指定行的下面一行读入编辑缓冲区。
Shell 编程 152
常见的 sed 编辑命令小结
q :退出,读取到指定行后退出 sed。
myvar= "west"
sed –n "/${myvar}/p" datafile
如何输入控制字符,如:回车、Esc、F1 等
以输入 回车 ( ^M ) 为例:
Shell 编程 154
一些 sed 行命令集
'/north/p' 打印所有包含 north 的行
'/north/!p' 打印所有不包含 north 的行
's/\.$//g' 删除以句点结尾的行中末尾的句点
's/^ *//g' 删除行首空格(命令中 ^ * 之间有两个空格)
's/ */ /g' 将连续多个空格替换为一个空格
命令中 */ 前有三个空格,后面是一个空格
'/^$/d’ 删除空行
's/^.//g' 删除每行的第一个字符,同 's/.//'
's/^/%/g' 在每行的最前面添加百分号 %
'3,5s/d/D/' 把第 3 行到第 5 行中每行的 第一个 d 改成 D
Shell 编程 155
awk 介绍
awk 是什么
awk 是一种用于处理数据和生成报告的编程语言
awk 可以在命令行中进行一些简单的操作,也可以被写成脚本来处理较大的
应用问题
awk 与 grep、sed 结合使用,将使 shell 编程更加容易
awk 如何工作
awk 逐行扫描输入 ( 可以是文件或管道等 ),按给定的模式查找出匹配的行,
然后对这些行执行 awk 命令指定的操作。
#!/bin/awk -f
awk_cmd1
... ...
Shell 编程 157
awk 的三种调用方式
awk_script 可以由一条或多条 awk_cmd 组成,每条 awk_cmd 各占一行。
每个 awk_cmd 由两部分组成:/pattern/{actions}
awk 命令的一般形式:
awk 'BEGIN {actions} 注意 BEGIN
/pattern1/{actions} 和 END都是
大写字母。
......
/patternN/{actions}
END {actions}' input_file
其中 BEGIN {actions} 和 END {actions}
Shell 编程 是可选的 158
awk 的执行过程
① 如果存在 BEGIN ,awk 首先执行它指定的 actions
② awk 从输入中读取一行,称为一条输入记录
③ awk 将读入的记录分割成数个字段,并将第一个字段放入变量
$1 中,第二个放入变量 $2 中,以此类推;$0 表示整条记录;
字段分隔符可以通过选项 -F 指定,否则使用缺省的分隔符。
④ 把当前输入记录依次与每一个 awk_cmd 中 pattern 比较:
如果相匹配,就执行对应的 actions;
如果不匹配,就跳过对应的 actions,直到完成所有的 awk_cmd
⑤ 当一条输入记录处理完毕后,awk 读取输入的下一行,重复上
面的处理过程,直到所有输入全部处理完毕。
⑥ awk 处理完所有的输入后,若存在 END,执行相应的 actions
⑦ 如果输入是文件列表,awk 将按顺序处理列表中的每个文件。
Shell 编程 159
awk 丼例
awk '/Mar/{print $1,$3}' shipped
^ 只匹配行首 ( 可以看成是行首的标志 )
$ 只匹配行尾 ( 可以看成是行尾的标志 )
* 一个单字符后紧跟 *,匹配 0个或多个此字符
[ ] 匹配 [] 内的任意一个字符 ( [^] 反向匹配 )
\ 用来屏蔽一个元字符的特殊含义
. 匹配任意单个字符
str1|str2 匹配 str1 或 str2
+ 匹配一个或多个前一字符
? 匹配零个或一个前一字符
Shell 编程 161
( ) 字符组
模式匹配
② 使用布尔 ( 比较 ) 表达式,表达式的值为真时执行相应的操作 (actions)
Shell 编程 162
模式匹配
复合表达式:&& ( 逻辑与 )、|| ( 逻辑或 )、! ( 逻辑非 )
注:表达式中有比较运算时,一般用圆括号括起来
Shell 编程 163
字段分隔符、重定向和管道
字段分隔符
awk 中的字段分隔符可以用 -F 选项指定,缺省是空格。
重定向与管道
awk '{print $1, $2 > "output"}' datafile2
Shell 编程 164
AWK 中的操作 ACTIONS
操作由一条或多条语句或者命令组成,语句、命令之间用分号 “ ; ” 隔开。
操作中还可以使用流程控制结构的语句
awk 命令
print 输出列表:打印字符串、变量或表达式,输出列表中各参数之间用逗号
隔开;若用空格隔开,打印时各输出之间没有空格
next:停止处理当前记录, 开始读取和处理下一条记录
awk 'BEGIN
{x=1;y=x;z="OK";
print "x=" x, "y=" y, "z=" z}'
用表达式赋值:
流控制结构举例:awkfile2
Shell 编程 167
AWK 中的变量
在 awk_script 中的表达式中要经常使用变量。awk 的变量基本可以分为:
字段变量,内置变量和自定义变量。
可以创建新的输出字段,比如:当前输入记录被分割为 8个字段,这时可以
通过对变量 $9 ( 或 $9 之后的字段变量 ) 赋值而增加输出字段,NF 的值也将随
之变化。
在表达式中出现不带双引号的字符串都被视为变量
如果自定义变量在使用前没有被赋值,缺省值为 0
或 空字符串
Shell 编程 170
变量传递
如何向命令行 awk 程序传递变量的值
awk 'awk_script' var1=val1 var2=val2 ... files
var 可以是 awk 内置变量或自定义变量。
var 的值在 awk 开始对输入的第一条记录应用 awk_script 前传入。如果在
awk_script 中已经对某个变量赋值,那么命令行上的赋值无效。
在 awk 脚本程序中不能直接使用 shell 的变量。
可以向 awk 可执行脚本传递变量的值,与命令行类似,即
Shell 编程 172
内置字符串函数
② 常见 awk 内置字符串函数
index(str,substr):返回子串 substr 在字符串 str 中第
一次出现的位置,若找不到,则返回值为 0
awk 'BEGIN{print index("peanut","an")}'
sprintf(format,exp1,...):返回一个指定格式的表达式,
格式 format 与 printf 的打印格式类似 ( 不在屏幕上输出 )
Shell 编程 173
内置字符串函数
sub(rexp,sub_str,target):在目标串 target 中寻找第
一个能够匹配正则表达式 rexp 的子串,并用字符串 sub_str
替换该子串。若没有指定目标串,则在整个记录中查找
awk 'BEGIN{str="water,water";sub(/at/,"ith",str);\
print str}'
awk 'BEGIN{split("11/15/2005",date,"/"); \
print date[2]}'
Shell 编程 175
内置系统函数
③ 常见 awk 内置系统函数
close(filename)
将输入或输出的文件 filename 关闭。
system(command)
此函数允许调用操作系统的指令,执行完毕后返回 awk
Shell 编程 176
AWK 的自定义函数
function fun_name (parameter_list) {
body-of-function
// 函数体,是 awk 语句块
}
parameter_list 是以逗号分隔的参数列表
自定义函数可以在 awk 程序的任何地方定义
函数名可包括字母、数字、下标线,但不可以数字开头
调用自定义的函数与调用内置函数的方法一样
Shell 编程 177
AWK 中的数组
数组使用前,无需预先定义,也不必指定数组元素个数
访问数组的元素
经常使用循环来访问数组元素
awk 'BEGIN{print \
split("123#456#789",mya,"#"); \
for (i in mya) {print mya[i]}}'
Shell 编程 178
字符串屏蔽
使用字符串或正则表达式时,有时需要在输出中加
入一新行或一个特殊字符。这时就需要字符串屏蔽。
awk 中常用的字符串屏蔽序列
\b 退格键 \t tab 键
\f 走纸换页 \n 新行
\r 回车键 \ddd 八进制值 ASCII 码
\c 任意其他特殊字符。如: \\ 为反斜线符号
awk 'BEGIN{print \
"\nMay\tDay\n\nMay\t\104\141\171"}'
Shell 编程 179
AWK 输出函数 PRINTF
基本上和 C 语言的语法类似
printf( [格式控制符], 参数列表 )
参数列表中可以有变量、数值数据或字符串,用逗号隔开
格式控制符:%[-][w][.p]fmt
%:标识一个格式控制符的开始,不可省略
-:表示参数输出时左对齐,可省略
w:一个数字,表示参数输出时占用域的宽度,可省略
.p:p是一个数值,表示最大字符串长度或小数位位数,可省略
fmt:一个小写字母,表示输出参数的数据类型,不可省略
Shell 编程 180
AWK 输出函数 PRINTF
常见的 fmt
c ASCII 字符 d 整数
f 浮点数,如 12.3 e 浮点数,科学记数法
g 自动决定用 e 或 f s 字符串
o 八进制数 x 十六进制数
awk 'BEGIN{printf \
"2 number:%8.4f %8.2f",999,888}'
Shell 编程 181
注意事项
为了避免碰到 awk 错误,要注意以下事项:
确保整个 awk_script 用单引号括起来
确保 awk_script 内所有引号都成对出现
确保用花括号括起动作语句,用圆括号括起条件语句
如果使用字符串,要保证字符串被双引号括起来
( 在模式中除外 )
awk 语言学起来可能有些复杂,但使用它来编写一行命令或小脚本并不太难。
awk 是 shell 编程的一个重要工具。在shell 命令或编程中,可以使用 awk 强
大的文本处理能力。
Shell 编程 182