竹磬网-邵珠庆の日记 生命只有一次,你可以用它来做些更多伟大的事情–Make the world a little better and easier


284月/100

最短CN域名在干啥?

发布在 邵珠庆

总共二十六个英语字母,由这二十六个字母组成的最短 CN域名都只想哪些网站,我在浏览器里一次输入,得到如下结果。

a.cn 没有任何网页,经查询该域名已被列入限制注册名单

b.cn 中,北京澳美新投资顾问有限公司所有

c.cn 中,北京澳美新投资顾问有限公司

d.cn 当乐网,手机游戏下载网站

e.cn 没有任何网页,经查询该域名已被列入限制注册名单

f.cn 没有任何网页,2003年被深圳市世强电脑科技有限公司注册

g.cn 大家都知道,谷歌花了不少银子买的,指向谷歌中国

h.cn 指向shanghai.114.cc(上海房地产网),没有作主域名,估计在待价而沽

i.cn 没有任何网页,经查询该域名已被列入限制注册名单

j.cn 指向简单生活网,一在线生活服务网站,还有点名气

k.cn 没有任何网页,2003年被北京保联网科技有限公司注册

l.cn 乐活网,也是一在线生活服务网站,不过我好像今天才听说。

m.cn 出现错误,打不开,经查询2003年被济南鑫达印刷包装有限公司注册

n.cn 没有任何网页,经查询2003年被北京计算机与网络研究中心注册

o.cn 网站叫都市圈,一分类信息网站

p.cn 不明白是个什么类型的网站

q.cn 网站叫摘吧,号称“中国文摘基地”

r.cn 指向dg.114.cc(东莞人才网),看来跟h.cn有着一样的命运

s.cn 2003年被北京智慧东方信息技术有限公司注册

t.cn 没有任何网页,2003年被Hangzhou 365 Internet Co.,Ltd注册

u.cn 网站叫看天下,是个图书阅读网站

v.cn 2003年被沈阳五星设计有限公司注册

w.cn 指向msn.ename.cn,看来是被易名中国给注册去了

x.cn 竟然指向的是陕西联通,注册者却不是,我晕!

y.cn 哇!竟然是2005年注册的,之前就没有人注册?

z.cn 指向rc.114.cc,与h.cn和r.cn命运一样。这家公司就厉害了,拥有三个这样 的域名

在查询的过程中,我发现这些域名大多是在2003年3月10日被人注册的 ,哪一天是什么日子?

从上面可以看出,只有8个 被真正投入使用中,其他要嘛没有,要嘛正中,还有的则没有被用作主域名。

y.cn让我好意外,2005年才被注册。2003年到2005年这段时间,玉米们在干啥?不会认为这样的域名 根本不可能 被自己注册到而懒得去查吧?

224月/100

各大浏览器 CSS3 和 HTML5 兼容速查表

发布在 邵珠庆

支持 CSS3HTML5 的浏览器越来越多,甚至包括最新版的 IE,当然,所谓支持仅仅是部分支持,因为 CSS3 和 Html5 的W3C 规范都尚未形成。如果你现在就希望使用 CSS3 和 HTML5 创建你的站点,至少要对各个浏览器对这两种新技术的支持情况有一个全面了解。

需要指出的是,即使同一个浏览器的同一个版本,在 Mac 和 Windows 两个平台,它们对 CSS3 和 HTML5 的支持也并不一致。本文是一份 Chrome, Safari, Firefox, Opera, IE 5 大浏览器,在 Mac 和 Windows 两个平台,对 CSS3 和 HTML5 各种功能的详细支持情况清单。

CSS3 属性

可以看出,全盘支持 CSS3 属性的浏览器有 Chrome 和 Safari,而且不管是 Mac 平台还是 Windows 平台全支持。

CSS3 选择器

除了 IE 家族和 Firefox 3,其它几乎全部支持。Chrome,Safari,Firefox 3.6,Opera 10.5 成绩最好 。

HTML5 Web 应用

Safari 对 HTML5 Web 应用的支持最好,除了地理定位功能,其它都支持。

HTML5 网页内嵌对象

这应该是 HTML5 最令人期待的东西,内置的画布,视频,音频等对象。全部支持的有 Chrome,Safari,Firefox 3.6,Opera 10.5。IE家族则全军覆没。

HTML5 音频编码

Opera 10.5 支持的最全面,IE 家族又是颗粒无收。

HTML5 视频编码

H.264 任重道远。

HTML5 各种表单对象

Mac 平台下的 Chrome 成绩最佳。这些表单对象让人想起了桌面程序。

HTML5 表单对象属性与行为

又一次想到了桌面程序。

结论

目前,对 CSS3 和 HTML5 支持最好的是 Safari,Chrome 次之,Firefox 3.6 和 Opera 10.5 旗鼓相当,IE家族最差。鉴于这种情况,假如你想使用这两项新技术创建一个先锋体验式站点,现在的 CSS3 和 HTML5 可以让你实现,假如你希望这个站点能被绝大多数人正常访问,现在还为时过早,折中的方案是,为不支持 CSS3 和 HTML5 某些功能的浏览器提供降级方案,当然,其中要涉及到很多问题,包括浏览器,版本,平台的探测,CSS Hack 等等大量工作,相信是得不偿失的。

184月/100

ThinkPHP单字母函数(快捷方法)使用总结

发布在 邵珠庆

1.U() URL组装 支持不同URL模式
U($url='',$vars='',$suffix=true,$domain=false)
  @param string $url URL表达式,格式:'[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...'
  @param string|array $vars 传入的参数,支持数组和字符串
  @param string $suffix 伪静态后缀,默认为true表示获取配置值
  @param boolean $domain 是否显示域名
  @return string

2.D() D函数用于实例化模型类 格式 [资源://][模块/]模型
D($name='',$layer='')
  @param string $name 资源地址
  @param string $layer 模型层名称
  @return Model

3.M() M函数用于实例化一个没有模型文件的Model
M($name='',$tablePrefix='',$connection='')
  @param string $name Model名称 支持指定基础模型 例如MongoModel:User
  @param string $tablePrefix 表前缀
  @param mixed $connection 数据库连接信息
  @return Model

4.I() 获取输入参数 支持过滤和默认值
I($name,$default='',$filter=null)
  使用方法:

I('id',0); //获取id参数 自动判断get或者post
I('post.name','','htmlspecialchars'); //获取$_POST['name']
I('get.'); //获取$_GET

5.B() 执行某个行为
B($name,$tag='',&$params=NULL)
  @param string $name 行为名称
  @param string $tag 标签名称(行为类无需传入)
  @param Mixed $params 传入的参数
  @return void

6.C() 读取及设置配置参数
C($name=null,$value=null,$default=null)
  @param string|array $name 配置变量
  @param mixed $value 配置值
  @param mixed $default 默认值
  @return mixed

7.E() 抛出异常处理
E($msg, $code=0)
  @param string $msg 异常消息
  @param integer $code 异常代码 默认为0
  @return void

8.G() 记录和统计时间(微秒)和内存使用情况
G($start,$end='',$dec=4)
  使用方法:
G('begin'); // 记录开始标记位
// ... 区间运行代码
G('end'); // 记录结束标签位
echo G('begin','end',6); //统计区间运行时间 精确到小数后6位
echo G('begin','end','m'); // 统计区间内存使用情况
  如果end标记位没有定义,则会自动以当前作为标记位
  其中统计内存使用需要 MEMORY_LIMIT_ON 常量为true才有效
  @param string $start 开始标签
  @param string $end 结束标签
  @param integer|string $dec 小数位或者m
  @return mixed

9.L()获取和设置语言定义(不区分大小写)
L($name=null,$value=null)
  @param string|array $name 语言变量
  @param mixed $value 语言值或者变量
  @return mixed

10.T()获取模版文件 格式 资源://模块@主题/控制器/操作
T($template='',$layer='')
  @param string $name 模版资源地址
  @param string $layer 视图层(目录)名称
  @return string

11.N() 设置和获取统计数据
N($key,$step=0,$save=false)
  使用方法:
N('db',1); // 记录数据库操作次数
N('read',1); // 记录读取次数
echo N('db'); // 获取当前页面数据库的所有操作次数
echo N('read'); // 获取当前页面读取次数
  @param string $key 标识位置
  @param integer $step 步进值
  @return mixed

12.A()A函数用于实例化控制器

格式:[资源://][模块/]控制器
A($name,$layer='',$level='')
  @param string $name 资源地址
  @param string $layer 控制层名称
  @param integer $level 控制器层次
  @return Controller|false

13.R() 远程调用控制器的操作方法
URL 参数格式 [资源://][模块/]控制器/操作
R($url,$vars=array(),$layer='')
  @param string $url 调用地址
  @param string|array $vars 调用参数 支持字符串和数组
  @param string $layer 要调用的控制层名称
  @return mixed

14.W()渲染输出Widget
W($name,$data=array())
  @param string $name Widget名称
  @param array $data 传入的参数
  @return void

15.S()缓存管理
S($name,$value='',$options=null)
  @param mixed $name 缓存名称,如果为数组表示进行缓存设置
  @param mixed $value 缓存值
  @param mixed $options 缓存参数
  @return mixed

16.F() 快速文件数据读取和保存 针对简单类型数据 字符串、数组
F($name, $value='',$path=DATA_PATH)
  @param string $name 缓存名称
  @param mixed $value 缓存值
  @param string $path 缓存路径
  @return mixed
124月/100

awk 用法

发布在 邵珠庆

调用AWK
有三种方式调用awk,第一种是命令行方式,如:
awk [-F field-separator]'commands' input-files(s)
这里,commands是真正的awk命令。本章将经常使用这种方法。
上面例子中,[-F域分隔符]是可选的,因为awk使用空格作为缺省的域分隔符,因此如果要浏览域间有空格的文本,不必指定这个选项,但如果要浏览诸如passwd文件,此文件各域以冒号作为分隔符,则必须指明- F选项,如:
awk -F:'commands'input-file
第二种方法是将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它。
第三种方式是将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
-f选项指明在文件awk_script_file中的awk脚本,input_file(s)是使用awk进行浏览的文件名。
awk脚本
在命令中调用awk时,awk脚本由各种操作和模式组成。
如果设置了-F选项,则awk每次读一条记录或一行,并使用指定的分隔符分隔指定域,但如果未设置-F选项,awk假定空格为域分隔符,并保持这个设置直到发现一新行。当新行出现时,awk命令获悉已读完整条记录,然后在下一个记录启动读命令,这个读进程将持续到文件尾或文件不再存在。
参照表1-1,awk每次在文件中读一行,找到域分隔符(这里是符号#),设置其为域n,直至一新行(这里是缺省记录分隔符),然后,划分这一行作为一条记录,接着awk再次启动下一行读进程。
表1-1 awk读文件记录的方式

域1 分隔符 域2 分隔符 域3 分隔符 域4及换行
P.Bunny(记录1) # 02/99 # 48 # Yellow/n
J.Troll(记录2) # 07/99 # 4842 # Brown-3/n

模式和动作
任何awk语句都由模式和动作组成。在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。
模式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行。END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志。如果不特别指明模式,awk总是匹配或打印行数。
实际动作在大括号{}内指明。动作大多数用来打印,但是还有些更长的代码诸如if和循环(looping)语句及循环退出结构。如果不指明采取动作,awk将打印出所有浏览出来的记录。
下面将深入讲解这些模式和动作。
域和记录
awk执行时,其浏览域标记为$1,$2...$n。这种方法称为域标识。使用这些域标识将更容易对域进行进一步处理。
使用$1,$3表示参照第1和第3域,注意这里用逗号做域分隔。如果希望打印一个有5个域的记录的所有域,不必指明$1,$2,$3,$4,$5,可使用$0,意即所有域.Awk浏览时,到达一新行,即假定到达包含域的记录末尾,然后执行新记录下一行的读动作,并重新设置域分隔。
注意执行时不要混淆符号$和shell提示符$,它们是不同的。
为打印一个域或所有域,使用print命令。这是一个awk动作(动作语法用圆括号括起来)。
1. 抽取域
真正执行前看几个例子,现有一文本文件grade.txt,记录了一个称为柔道数据库的行信息。
$pg grade.txt

此文本文件有7个域,即(1)名字、(2)升段日期、(3)学生序号、(4)腰带级别、(5)年龄、(6)目前比赛积分、(7)比赛最高分。
2. 保存awk输出
有两种方式保存shell提示符下awk脚本的输出。最简单的方式是使用输出重定向符号>文件名,下面的例子重定向输出到文件wow。
$awk '{print $0}' grade.txt>wow
使用这种方法要注意,显示屏上不会显示输出结果。因为它直接输出到文件。只有在保证输出结果正确时才会使用这种方法。它也会重写硬盘上同名数据。
第二种方法是使用tee命令,在输出到文件的同时输出到屏幕。在测试输出结果正确与否时多使用这种方法。例如输出重定向到文件delete_me_and_die,同时输出到屏幕。使用这种方法,在awk命令结尾写入|tee delete_me_and_die。
$awk '{print $0}' grade.txt|tee delete_me_and_die
3. 使用标准输入
在深入讲解这一章之前,先对awk脚本的输入方法简要介绍一下。实际上任何脚本都是从标准输入中接受输入的。为运行本章脚本,使用awk脚本输入文件格式,例如:
$belts.awk grade_student.txt
也可替代使用下述格式:
使用重定向方法:
$belts.awk < grade2.txt
或管道方法:
$grade2.txt|belts.awk
4. 打印所有记录
$awk '{print $0}' grade.txt
awk读每一条记录。因为没有模式部分,只有动作部分{print $0}(打印所有记录),这个动作必须用花括号括起来。上述命令打印整个文件。
5. 打印单独记录
假定只打印学生名字和腰带级别,查看域所在列,可知为field-1和field-4,因此可以使用$1和$4,但不要忘了加逗号以分隔域。
$awk '{print $1,$4}' grade.txt
6. 打印报告头
上述命令输出在名字和腰带级别之间用一些空格使之更容易划分,也可以在域间使用tab键加以划分。为加入tab键,使用tab键速记引用符/t,后面将对速记引用加以详细讨论。也可以为输出文本加入信息头。本例中加入name和belt及下划线。下划线使用/n,强迫启动新行,并在/n下一行启动打印文本操作。打印信息头放置在BEGIN模式部分,因为打印信息头被界定为一个动作,必须用大括号括起来。在awk查看第一条记录前,信息头被打印。
$awk 'BEGIN {print "Name    Belt/n---------------------"}
{print $1"/t"$4}'grade.txt
Name        Belt
----------------------
M.Transley  Green
(省略)
7. 打印信息尾
如果在末行加入end of report信息,可使用END语句。END语句在所有文本处理动作执行完之后才被执行。END语句在脚本中的位置放置在主要动作之后。下面简单打印头信息并告之查询动作完成。
$awk 'BEGIN {print "Name/n--------"}{print $1}END{"end of report"}'grade.txt
Name
--------------
M.Transley
(……)
8. awk错误信息提示
在碰到awk错误时,可相应查找:
• 确保整个awk命令用单引号括起来。
• 确保命令内所有引号成对出现。
• 确保用花括号括起动作语句,用圆括号括起条件语句。
• 可能忘记使用花括号,也许你认为没有必要,但awk不这样认为,将按之解释语法。
元字符
这里是awk中正则表达式匹配操作中经常用到的字符。
/ ^ $ . [] | () * + ?
+,?这里没讲到,因为它们只适用于awk而不适用于grep或sed
+ 使用+匹配一个或多个字符。
? 匹配模式出现频率。例如使用/XY?Z/匹配XYZ或YZ。
条件操作符

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

1. 匹配
为使一域号匹配正则表达式,使用符号‘~’后紧跟正则表达式,也可以用if语句。awk中if后面的条件用()括起来。
观察文件grade.txt,如果只要打印brown腰带级别可知其所在域为field-4,这样可以写出表达式{if($4~/brown/)print}意即如果field-4包含brown,打印它。如果条件满足,则打印匹配记录行。可以编写下面脚本,因为这是一个动作,必须用花括号{}括起来。
$awk '{if($4~/brown/)print $0}' grade.txt
J.Troll   07/99   4842   Brown-3   12  26   26
(……)
匹配记录找到时,如果不特别声明,awk缺省打印整条记录。使用if语句开始有点难,但不要着急,因为有许多方法可以跳过它,并仍保持同样结果。下面例子意即如果记录包含模式brown,就打印它:
$awk '$0 ~ /Brown/' grade.txt
J.Troll   07/99   4842   Brown-3   12  26   26
(……)
2. 小于等于
$awk '{if($6<$7)print $1}'grade.txt
3.行首
$awk '/^48/'input-file
复合操作符:
&& AND : 语句两边必须同时匹配为真。
|| OR:语句两边同时或其中一边匹配为真。
! 非求逆
awk内置变量

内置变量 含义
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行-F选项
NF 浏览记录的域个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符

ARGC支持命令行中传入awk脚本的参数个数。ARGV是ARGC的参数排列数组,其中每一元素表示为ARGV[n],n为期望访问的命令行参数。
ENVIRON支持系统设置的环境变量,要访问单独变量,使用实际变量名,例如ENVIRON["EDITOR"] ="Vi"。
FILENAME支持awk脚本实际操作的输入文件。因为awk可以同时处理许多文件,因此如果访问了这个变量,将告之系统目前正在浏览的实际文件。
FNR支持awk目前操作的记录数。其变量值小于等于NR。如果脚本正在访问许多文件,每一新输入文件都将重新设置此变量。
FS用来在awk中设置域分隔符,与命令行中-F选项功能相同。缺省情况下为空格。如果用逗号来作域分隔符,设置FS=","。
NF支持记录域个数,在记录被读之后再设置。
OFS允许指定输出域分隔符,缺省为空格。如果想设置为#,写入OFS="#"。
ORS为输出记录分隔符,缺省为新行(/n)。
RS是记录分隔符,缺省为新行(/n)。
NF、NR和FILENAME
下面看一看awk内置变量的例子。
要快速查看记录个数,应使用NR。比如说导出一个数据库文件后,如果想快速浏览记录个数,以便对比于其初始状态,查出导出过程中出现的错误。使用N R将打印输入文件的记录个数。print NR放在END语法中。
$awk 'END {print NR}'grade.txt
以下例子中,所有学生记录被打印,并带有其记录号。使用NF变量显示每一条读记录中有多少个域,并在END部分打印输入文件名。
$awk '{print NF,NR,$0}END{print FILENAME}' grade.txt
7  1  M.Transley   05/99   48311   Green  8   40   44
7  2  J.Lulu       06/99   48317   green  9   24   26
(……)
grade.txt
在从文件中抽取信息时,最好首先检查文件中是否有记录。下面的例子只有在文件中至少有一个记录时才查询Brown级别记录。使用AND复合语句实现这一功能。意即至少存在一个记录后,查询字符串Brown,最后打印结果。
$awk '{if(NR>0 && $4~/Brown/)print $0}'grade.txt
NF的一个强大功能是将变量$PWD的返回值传入awk并显示其目录。这里需要指定域分隔符/。
$pwd
/usr/local/etc
$echo $pwd|awk -F/ '{print $NF}'
etc
awk操作符
1. 设置输入域到域变量名
在awk中,设置有意义的域名是一种好习惯,在进行模式匹配或关系操作时更容易理解。一般的变量名设置方式为name=$n,这里name为调用的域变量名,n为实际域号。例如设置学生域名为name,级别域名为belt,操作为name=$1;belts=$4。注意分号的使用,它分隔awk命令。下面例子中,重新赋值学生名域为name,级别域为belts。查询级别为Yellow的记录,并最终打印名称和级别。
$awk '{name=$1;belt=$4;if(belt ~Yellow/)print name"is belt"belts}'grade.txt
P.Bunny is belt Yellow.
2. 域值比较操作
有两种方式测试一数值域是否小于另一数值域。
1) 在BEGIN中给变量名赋值。
2) 在关系操作中使用实际数值。
通常在BEGIN部分赋值是很有益的,可以在awk表达式进行改动时减少很多麻烦。
使用关系操作必须用圆括号括起来。
下面的例子查询所有比赛中得分在27点以下的学生。
用引号将数字引用起来是可选的,“27”、27产生同样的结果。
$awk '{if{$6<27)print $0}'grade.txt
3. 修改数值域取值
当在awk中修改任何域时,重要的一点是要记住实际输入文件是不可修改的,修改的只是保存在缓存里的awk复本。awk会在变量NR或NF变量中反映出修改痕迹。
为修改数值域,简单的给域标识重赋新值,如: $1=$1+5,会将域1数值加5,但要确保赋值域其子集为数值型。
修改M.Tansley的目前级别分域,使其数值从40减为39,使用赋值语句$6=$6-1,当然在实施修改前首先要匹配域名。
$awk '{if($1=="M.Tansley") $6=$6-1;print $1,$6,$7}' grade.txt
4. 修改文本域
修改文本域即对其重新赋值。需要做的就是赋给一个新的字符串。在J.Troll中加入字母,使其成为J.L.Troll,表达式为$1="J.L.Troll",记住字符串要使用双引号(" "),并用圆括号括起整个语法。
$awk '{if($1==J.Troll")($1=J.L.Troll);print $1}' grade.txt
5. 只显示修改记录
上述例子均是对一个小文件的域进行修改,因此打印出所有记录查看修改部分不成问题,但如果文件很大,记录甚至超过100,打印所有记录只为查看修改部分显然不合情理。在模式后面使用花括号将只打印修改部分。取得模式,再根据模式结果实施操作,可能有些抽象,现举一例,只打印修改部分。注意花括号的位置。
$awk '{if($1==J.Troll"){$1=J.L.Troll ;print $1}}' grade.txt
6. 创建新的输出域
在awk中处理数据时,基于各域进行计算时创建新域是一种好习惯。创建新域要通过其他域赋予新域标识符。如创建一个基于其他域的加法新域{$4=$2+$3},这里假定记录包含3个域,则域4为新建域,保存域2和域3相加结果。
在文件grade.txt中创建新域8保存域目前级别分与域最高级别分的减法值。表达式为‘{$8=$7-$6}’,语法首先测试域目前级别分小于域最高级别分。新域因此只打印其值大于零的学生名称及其新域值。在BEGIN部分加入tab键以对齐报告头。
$awk 'BEGIN{print "Name/t Difference"}{if($6<$7){$8=$7-$6;print $1,$8}}' grade.txt
7. 增加列值
为增加列数或进行运行结果统计,使用符号+=。增加的结果赋给符号左边变量值,增加到变量的域在符号右边。例如将$1加入变量total,表达式为total+=$1。列值增加很有用。许多文件都要求统计总数,但输出其统计结果十分繁琐。在awk中这很简单,请看下面的例子。
将所有学生的‘目前级别分’加在一起,方法是tot+=$6,tot即为awk浏览的整个文件的域6结果总和。所有记录读完后,在END部分加入一些提示信息及域6总和。不必在awk中显示说明打印所有记录,每一个操作匹配时,这是缺省动作。
$ awk '(tot+=$6);END {print "Club student total points:" tot}' grade.txt
M.Transley   05/99   48311   Green  8   40   44
(……)
Club student total points:155
如果文件很大,你只想打印结果部分而不是所有记录,在语句的外面加上圆括号()即可。
$ awk '{(tot+=$6);END {print "Club student total points:" tot}}' grade.txt
Club student total points:155

内置的字符串函数
-----------------------------------------------------------
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
sprint(fmt,exp)   返回经fmt格式化后的exp
sub(r,s)          用$0中最左边最长的子串代替s
substr(s,p)       返回字符串s中从p开始的后缀部分
substr(s,p,n)     返回字符串s中从p开始长度为n的后缀部分
-----------------------------------------------------------
gsub函数有点类似于sed查找和替换。它允许替换一个字符串或字符为另一个字符串或字符,并以正则表达式的形式执行。第一个函数作用于记录$0,第二个gsub函数允许指定目标,然而,如果未指定目标,缺省为$0。
index(s,t)函数返回目标字符串s中查询字符串t的首位置。length函数返回字符串s字符长度。match函数测试字符串s是否包含一个正则表达式r定义的匹配。split使用域分隔符fs将字符串s划分为指定序列a。sprint函数类似于printf函数(以后涉及),返回基本输出格式fmt的结果字符串exp.sub(r,s)函数将用s替代$0中最左边最长的子串,该子串被(r)匹配。
sub(s,p)返回字符串s在位置p后的后缀。substr(s,p,n)同上,并指定子串长度为n。
1. gsub
要在整个记录中替换一个字符串为另一个,使用正则表达式格式, /目标模式/,替换模式/。例如改变学生序号4842到4899:
$ awk 'gsub(/4842/,4899){print $0}' grade.txt
J.Troll   07/99  4899  Brown-3  12   26   26
2. index
查询字符串s中t出现的第一位置。必须用双引号将字符串括起来。例如返回目标字符串Bunny中ny出现的第一位置,即字符个数。
$ awk 'BEGIN {print index("Bunny","ny")}' grade.txt
4
3. length
返回所需字符串长度,例如检验字符串J.Troll返回名字及其长度,即人名构成的字符个数。
$ awk '$1=="J.Troll" {print length($1) " " $1}' grade.txt
7 J.Troll
4. match
match测试目标字符串是否包含查找字符的一部分。可以对查找部分使用正则表达式,返回值为成功出现的字符排列数。如果未找到,返回0,第一个例子在ANCD中查找d。因其不存在,所以返回0。第二个例子在ANCD中查找D。因其存在,所以返回ANCD中D出现的首位置字符数。第三个例子在学生J.Lulu中查找u。
$ awk 'BEGIN {print match("ANCD",/d/)}'
0
$ awk 'BEGIN {print match("ANCD",/C/)}'
3
$ awk '$1=="J.Lulu" {print match($1,"u")}' grade.txt
4
5. split
使用split返回字符串数组元素个数。例如;
$ awk 'BEGIN{print split("123#456#789",myarray,#)}'
3
split返回数组myarray的下标数。数组myarray取值如下:
Myarray[1]=123
Myarray[2]=456
Myarray[3]=789
6. sub
使用sub发现并替换模式的第一次出现位置。学生J.Troll的记录有两个值一样,“目前级别分”与“最高级别分”。只改变第一个为29,第二个仍为24不动,操作命令为sub(/26/,"29",$0),只替换第一个出现24的位置。注意J.Troll记录需存在。
7. substr
substr是一个很有用的函数。它按照起始位置及长度返回字符串的一部分。如果给定长度值远大于字符串长度,awk将从起始位置返回所有字符,要抽取L.Tansley
的姓,只需从第3个字符开始返回长度为7。可以输入长度99,awk返回结果相同。
$ awk '$1=="L.Tansley" {print substr($1,3,99)}' grade.txt
Tansley
substr的另一种形式是返回字符串后缀或指定位置后面字符。这里需要给出指定字符串及其返回字串的起始位置。例如,从文本文件中抽取姓氏,需操作域1,并从第三个字符开始:
$ awk '{print substr($1,3)}' grade.txt
还有一个例子,在BEGIN部分定义字符串,在END部分返回从第t个字符开始抽取的子串。
$ awk 'BEGIN {STR="A FEW GOOD MEN"} END {print substr(STR,7)}'grade.txt
GOOD MEN
8. 从shell中向awk传入字符串
awk脚本大多只有一行,其中很少是字符串表示的。大多要求在一行内完成awk脚本,这一点通过将变量传入awk命令行会变得很容易。现就其基本原理讲述一些例子。例如:

字符串屏蔽序列
使用字符串或正则表达式时,有时需要在输出中加入一新行或查询一元字符。
打印一新行时,(新行为字符/n),给出其屏蔽序列,以不失其特殊含义,用法为在字符串前加入反斜线。例如使用/n强迫打印一新行。
如果使用正则表达式,查询花括号({}),在字符前加反斜线,如//{/,将在awk中失掉其特殊含义。

awk中使用的屏蔽序列
/b 退格键         /t tab键
/f 走纸换页       /ddd 八进制值
/n 新行           /c 任意其他特殊字符,例如//为反斜线符号
/r 回车键

awk输出函数printf
每一种printf函数(格式控制字符)都以一个%符号开始,以一个决定转换的字符结束。转换包含三种修饰符。printf函数基本语法是printf([格式控制符],参数),格式控制字符通常在引号里。

awk printf修饰符
-        左对齐
Width    域的步长,用0表示0步长
.prec    最大字符串长度,或小数点右边的位数

 

awk printf格式
%c     ASCII字符
%d     整数
%e     浮点数,科学记数法
%f     浮点数,例如(123.44)
%gawk  决定使用哪种浮点数转换e或者f
%o     八进制数
%s     字符串
%x     十六进制数

1. 字符转换
管道输出65到awk。printf进行ASCII码字符转换。这里也加入换行,因为缺省情况下printf不做换行动作。
$echo "65" | awk '{printf "%c/n",$0}'
A
当然也可以按同样方式使用awk得到同样结果。
$ awk 'BEGIN {printf "%c/n",65}'
A
所有的字符转换都是一样的,下面的例子表示进行浮点数转换后‘999’的输出结果。整数传入后被加了六个小数点。
$ awk 'BEGIN{printf "%f/n",999}
999.000000
2. 格式化输出
打印所有的学生名字和序列号,要求名字左对齐,15个字符长度,后跟序列号。注意/n换行符放在最后一个指示符后面。输出将自动分成两列。
$ awk '{printf "%-15s %s/n",$1,$3} grade.txt
3. 向一行awk命令传值
在查看awk脚本前,先来查看怎样在awk命令行中传递变量。
在awk执行前将值传入awk变量,需要将变量放在命令行中,格式如下:
awk 命令变量=输入文件值
下面的例子在命令行中设置变量AGE等于10,然后传入awk中,查询年龄在10岁以下的所有学生。
$ awk'{if($5<AGE) print $0}' AGE=10 grade.txt
要快速查看文件系统空间容量,观察其是否达到一定水平,可使用下面awk一行脚本。因为要监视的已使用空间容量不断在变化,可以在命令行指定一个触发值。首先用管道命令将df -k 传入awk,然后抽出第4列,即剩余可利用空间容量。使用$4 ~/^[0-9]/取得容量数值(1024块)而不是df的文件头,然后对命令行与‘ if($4<TRIGGER)’上变量TRIGGER中指定的值进行查询测试。

 

4. awk脚本文件
可以将awk脚本写入一个文件再执行它。命令不必很长(尽管这是写入一个脚本文件的主要原因),甚至可以接受一行命令。这样可以保存awk命令,以使不必每次使用时都需要重新输入。使用文件的另一个好处是可以增加注释,以便于理解脚本的真正用途和功能。
使用前面的几个例子,将之转换成awk可执行文件。像原来做的一样,将学生目前级别分相加awk '(tot+=$6)END{print "club student total points:"tot}'grade.txt。创建新文件student_tot.awk,给所有awk程序加入awk扩展名是一种好习惯,这样通过查看文件名就知道这是一个awk程序。如下:

第一行是!/bin/awk -f。这很重要,没有它自包含脚本将不能执行。这一行告之脚本系统中awk的位置。通过将命令分开,脚本可读性提高,还可以在命令之间加入注释。这里加入头信息和结尾的平均值。基本上这是一个一行脚本文件。
执行时,在脚本文件后键入输入文件名,但是首先要对脚本文件加入可执行权限。
系统中运用的帐号核实程序检验数据操作人的数据输入,不幸的是这个程序有一点错误,或者应该说是“非文本特征”。如果一个记录被发现包含一个错误,它应该一次只打印一行“ERROR*”,但实际上打印了许多这样的错误行。这会给帐号管理员造成误解,因此需要用awk脚本过滤出错误行的出现频率,使得每一个失败记录只对应一个错误行。
在awk实施过滤前先看看部分文件:

5. 在awk中使用FS变量
如果使用非空格符做域分隔符(FS)浏览文件,例如#或:,编写这样的一行命令很容易,因为使用FS选项可以在命令行中指定域分隔符。
$ awk -F:'awk {print $0}' input-file
使用awk脚本时,记住设置FS变量是在BEGIN部分。如果不这样做,awk将会发生混淆,不知道域分隔符是什么。下述脚本指定FS变量。脚本从/etc/passwd文件中抽取第1和第5域,通过分号“;”分隔passwd文件域。第1域是帐号名,第5域是帐号所有者。

文本包括了比实际命令更多的信息,没关系,仔细研读文本后,就可以精确知道其功能及如何调用它。
不要忘了增加脚本的可执行权限,然后将变量和赋值放在命令行脚本名字后、输入文件前执行。
$ age.awk AGE=10 grade.txt
同样可以使用前面提到的管道命令传值,下述awk脚本从du命令获得输入,并输出块和字节数。

awk数组
前面讲述split函数时,提到怎样使用它将元素划分进一个数组。这里还有一个例子:
$ awk 'BEGIN{print split("123#456#789",myarray,#)}'
3
在上面的例子中,split返回数组myarray下标数。实际上myarray数组为:
Myarray[1]=123
Myarray[2]=456
Myarray[3]=789
数组使用前,不必定义,也不必指定数组元素个数。经常使用循环来访问数组。下面是一种循环类型的基本结构:
For (element in array ) print array[element]
对于记录“123#456#678”,先使用split函数划分它,再使用循环打印各数组元素。操作脚本如下:

数组和记录
上面的例子讲述怎样通过split函数使用数组。也可以预先定义数组,并使用它与域进行比较测试,下面的例子中将使用更多的数组。
下面是从空手道数据库卸载的一部分数据,包含了学生级别及是否是成人或未成年人的信息,有两个域,分隔符为(#),文件如下:

脚本功能是读文件并输出下列信息。
1) 俱乐部中Yellow、Orange和Red级别的人各是多少。
2) 俱乐部中有多少成年人和未成年人。
查看文件,也许20秒内就会猜出答案,但是如果记录超过6 0个又怎么办呢?这不会很容易就看出来,必须使用awk脚本。
首先看看awk脚本,然后做进一步讲解。

BEGIN部分设置FS为符号#,即域分隔符,因为要查找Yellow、Orange和Red三个级别。然后在脚本中手工建立数组下标对学生做同样的操作。注意,脚本到此只有下标或元素,并没有给数组名本身加任何注释。初始化完成后,BEGIN部分结束。记住BEGIN部分并没有文件处理操作。
现在可以处理文件了。首先给数组命名为color,使用循环语句测试域1级别列是否等于数组元素之一(Yellow、Orange或Red),如果匹配,依照匹配元素将运行总数保存进数组。同样处理数组‘Senior_or_junior’,浏览域2时匹配操作满足,运行总数存入junior或senior的匹配数组元素。
END部分打印浏览结果,对每一个数组使用循环语句并打印它。
注意在打印语句末尾有一个/符号,用来通知awk(或相关脚本)命令持续到下一行,当输入一个很长的命令,并且想分行输入时可使用这种方法。运行脚本前记住要加入可执行权限。