我的学习历程  
ASP.NET+Atlas+Linux学习历程
公告
  • 希望能够为中国的计算机事业出一份力,给买不起书的人写写教程!

    昵称:剑落飘香
    园龄:5年3个月
    粉丝:0
    关注:1
日历
<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910
统计
  • 随笔 - 15
  • 文章 - 3
  • 评论 - 6
  • 引用 - 0

导航

搜索

 
 

常用链接

最新随笔

我的标签

随笔档案

文章档案

最新评论

阅读排行榜

评论排行榜

推荐排行榜

 

2008年3月7日

JQuery.js是一个不可多得的JS框架,只要使用你就会迷上它,这里可以看到它的基础教程
http://wiki.jquery.org.cn/doku.php


<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>JQuery实现全选和反选</title>
    <script language="javascript" type="text/javascript" src="js/jquery-1.2.1.pack.js"></script>
    <script type="text/javascript">
    function CheckAll()
    {
        //取消反选的选中状态
        if($("#otherCheck")[0].checked)
        {
            $("#otherCheck")[0].checked=false;
        }
        if($("#allCheck")[0].checked)
        {
            //从div1中获取所有属性type=checkbox的input元素
            $('#div1 input[@type=checkbox]').each(function(i)
            {
                this.checked=true;
            });
        }
        else
        {
            $('#div1 input[@type=checkbox]').each(function(i)
            {
                this.checked=false;
            });
        }
       
    }
    function CheckOther()
    {
    //取消全选的选中状态
        if($("#allCheck")[0].checked)
        {
            $("#allCheck")[0].checked=false;
        }
        if($("#otherCheck")[0].checked)
        {
            $('#div1 input[@type=checkbox]').each(function(i)
            {
                if(this.checked)
                {
                    this.checked=false;
                }
                else
                {
                    this.checked=true;
                }
               
            });
        }
        else
        {
             $('#div1 input[@type=checkbox]').each(function(i)
            {
                if(this.checked)
                {
                    this.checked=false;
                }
                else
                {
                    this.checked=true;
                }
               
            });
        }
    }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div id="div1">
        <input type="checkbox"/>A<br />
        <input type="checkbox"/>B<br />
        <input type="checkbox"/>C<br />
        <input type="checkbox"/>D<br />
        <input type="checkbox"/>E<br />
        <input type="checkbox"/>F<br />
        <input type="checkbox"/>G<br />
        </div>
        <div id="div2">
        <input type="checkbox" id="allCheck" onclick="CheckAll();" />全选
        &nbsp;&nbsp
        <input type="checkbox" id="otherCheck" onclick="CheckOther();" />反选
        </div>
    </div>
    </form>
</body>
</html>

posted @ 2008-03-07 11:18 剑落飘香 阅读(4682) 评论(4) 编辑

2007年10月7日

一.ScriptManagerProxy控件概述

由于ScriptManager是整个页面的脚本控制器,所以一个ASPX页面上只能有一个ScriptManager控件。如果在项目在存在了母版页,并在母版页中已经应用了ScriptManager,而在内容页中又需要引入其他的WEB服务的话,该如何处理?
    这个时候ScriptManagerProxy就派上用场了。我们在内容页中可以用ScriptManagerProxy代理ScriptManagerProxy的功能,它的用法与ScriptManager完全相似:

<asp:ScriptManagerProxy id="ScriptManagerProxy1" runat="server">

    
<Services>

                
<asp:ServiceReference Path="CalculWebService.asmx" />

     
</Services>

</asp:ScriptManagerProxy>
在它下面可以添加的子标签有:Services,Scripts,AuthenticationService,ProfileService
或许有人说可以把服务和脚本都在母版页里面加载更省事,但是有时不同的内容页需要不同的脚本,这样做会降低效率。
2.用实例演示ScriptManagerProxy的应用
(1)首先,在网站下面添加一个母版页,命名为:MasterPage.master,添加如下控件:

(2)在根目录下添加js文件,JScript1.js,内容如下:
// JScript 文件
//求和】
function GetSum()
{
    var num1=document.getElementById("Text1").value;
    var num2=document.getElementById("Text2").value;
    sum(num1,num2);
}
function sum(m,n)
{
    alert(eval(m)+eval(n));
}
(3)现在在母版页中写入加载这个js文件的语句
<asp:ScriptManager ID="ScriptManager1" runat="server">
        <Scripts>
        <asp:ScriptReference Path="JScript1.js" />
        </Scripts>
        </asp:ScriptManager>
(4)新建一个WEB页面,命名为Default2.aspx,选择其母版页MasterPage.master;
添加控件后效果如下:

(5)新建JS文件JScript2.js,代码如下:
// JScript 文件
//求积
function GetProduct()
{
    var num1=document.getElementById("Txt1").value;
    var num2=document.getElementById("Txt2").value;
    product(num1,num2);
}
function product(a,b)
{
    alert(eval(a)*eval(b));
}
现在在Default.aspx2中引用这个文件就OK了,哈哈ScriptManagerProxy派上用场了,代码如下:
<asp:ScriptManagerProxy id="ScriptManagerProxy" runat="server">
    <Scripts>
        <asp:ScriptReference Path="JScript2.js" />
        </Scripts>
    </asp:ScriptManagerProxy>
OK了,运行测试一下吧!



posted @ 2007-10-07 23:23 剑落飘香 阅读(250) 评论(0) 编辑
 
 

首先,新建一个AJAXEnableWebSite,在default.aspx中添加如下控件:

注意:GridView控件和其数据源SqlDataSource控件放在updatepanel控件中,打开GridView的翻页功能,在updatepanel控件外放置一个updateProgress控件和Label控件,Label控件用于显示加载的时间,可以判断是否实现局部刷新。因为updatepane控件内的内容会被更新,其外的控件则不会更新,可以说UpdatePanel是实现局部刷新的关键。
在UpdateProgress控件中写入更新时的提示,如上图。
   下面,为了能够清楚的看到局部刷新的效果,并证明进行的局部刷新,我们的page_load()中加入了:
        Label1.Text = DateTime.Now.ToString();//显示页面加载的时间。
在GridView控件的翻页事件中加入如下代码来延迟进程:
    protected void GridView1_PageIndexChanged(object sender, EventArgs e)
    {
        System.Threading.Thread.Sleep(2000);
    }
好了,运行一下,就可以看到效果了。
你可以看到当翻页效果实现时,Label1上面的时间并没有变,说明实现了局部刷新。

posted @ 2007-10-07 22:17 剑落飘香 阅读(115) 评论(0) 编辑

2006年11月27日

#!/bin/bash
clear
record_file=passwd
again=""
while [ "$again" = "" ]
do
clear
echo "            用户信息主菜单"
echo "=================================="
echo "1、  打印当前所有记录"
echo "2、  打印当前所有记录(格式化后的)"
echo "3、  打印用户名和用户ID"
echo "4、  打印(格式化了的)用户名和用户ID"
echo "5、  查询特定记录"
echo "6、  增加新记录"
echo "7、  删除记录"
echo "Q----退出"
echo -n "你的选择是:"
read num
case $num in
1)
printf "\n"
awk -F ":" '{print $1 " " $2" " $3 " " $4 " " $5 " " $6 " " $7}' passwd
printf "\n"
echo -n "按回车键继续....."
read again;;
2)
printf "\n"
sort +1 passwd | awk -F ":" '{print $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $6 "\t" $7 "\t"}'
printf "\n"
echo -n "按回车键继续....."
read again;;
3)
printf "\n"
awk -F ":" '{print $1 "," $3}' passwd
printf "\n"
echo -n "按回车键继续....."
read again
;;
4)
printf "\n"
sort +1 passwd | awk -F ":" '{print "用户名:" $1 "\t" "用户ID:" $3}'
printf "\n"
echo -n "按回车键继续....."
read again;;
5)
printf "\n"
echo -n "输入关键字:"
read keyword
                                                                                                                                              
;;
Q)
echo "=============================="
echo "    Thanks for use!  ^_^"
echo "=============================="
again=quit;;
q)
echo "=============================="
echo "    Thanks for use!  ^_^"
echo "=============================="
again=quit;;
"")echo -n "Selection not entered. Press Enter to continue…"
read again;;
*)
echo -n "无效的代码,请按回车健继续....."
read again
;;
esac
done


posted @ 2006-11-27 22:39 剑落飘香 阅读(181) 评论(0) 编辑
 
请教SORT的详细用法

sort

cat students
John Johnsen    john.johnsen@tp.com     503.555.1111
Hassaan Sarwar  hsarwar@k12.st.or       503.444.2132
David Kendall   d_kendall@msnbc.org     229.111.2013

sort students
David Kendall   d_kendall@msnbc.org     229.111.2013
Hassaan Sarwar  hsarwar@k12.st.or       503.444.2132
John Johnsen    john.johnsen@tp.com     503.555.1111

sort +1 students
根据第2字段 (字段号1) 开始的整行作为排序关键字
John Johnsen    john.johnsen@tp.com     503.555.1111
David Kendall   d_kendall@msnbc.org     229.111.2013
Hassaan Sarwar  hsarwar@k12.st.or       503.444.2132

sort +3 -r -b students
以电话号码为关键字,对文件进行反向排序 (-b用于忽略字段之间的空格)
John Johnsen    john.johnsen@tp.com     503.555.1111
Hassaan Sarwar  hsarwar@k12.st.or       503.444.2132
David Kendall   d_kendall@msnbc.org     229.111.2013

sort +1 -2 +3 -b students
将姓氏为主关键字,将电话号码作为次关键字
John Johnsen    john.johnsen@tp.com     503.555.1111
David Kendall   d_kendall@msnbc.org     229.111.2013
Hassaan Sarwar  hsarwar@k12.st.or       503.444.2132

sort -k start,end files (关键字开始列,关键字结束列)
sort -rn -k 2,2 students

John Johnsen    john.johnsen@tp.com     503.555.1111
Hassaan Sarwar  hsarwar@k12.st.or       503.444.2132
David Kendall   d_kendall@msnbc.org     229.111.2013

sort -t: -k3,3 -k4,4 -k6,6 -k7n,7

-k3,3 就是只征对第3列排序,不排序后面的列
相当于 sort -t: +2 -3 +3 -4 +5 -6 +6n -7
-k7n 是对第7列按数字排序

现有一组数据文件进行排序,准备使用sort命令完成。但是测试并不成功,不知为何。请大家指点:
1。数据字段不是固定长度。
2。数据字段位置可辨,行首及行中、行尾三种情况
例如:
11,222,33
2,12,90
23,235,3
11111111,0,10
33,222222,22
0,90,222222222

求助:请问按行首排序得sort命令如何?行中、行尾呢?

sort -n -t, +0 -1 +1 -2 +2 -3 filename

看虚存:
#ps av |sort +5 -r |head -n 5
看实存:
#ps av |sort +6 -r |head -n 5
看内存%:
# ps au |head -n 1; ps au |egrep -v "RSS"|sort +3 -r |head -n 5


du | sort -n

sort按照指定的分割符把输入分割。按照指定列对文件排序
sort [-t 分割符] [-r逆序] [+n指定用来排序的列] file
$sort -t: passwd
以:分割行。然后按照分类键0排序
$sort -t: -r passwd
排序求逆
$sort -t: +1 passwd
按照第二列的值进行排序
$sort -t: +2n passwd
按照第三列按数值大小排序
$sort -t: +0 -2 +3 passwd
按照域0排序,忽略域2,然后使用域3排序
sort -t: -k3,3 -k4,4 -k6,6 -k7n,7

-k3,3 就是只征对第3列排序,不排序后面的列
相当于 sort -t: +2 -3 +3 -4 +5 -6 +6n -7
-k7n 是对第7列按数字排序


现有一组数据文件进行排序,准备使用sort命令完成。但是测试并不成功,不知为何。请大家指点:
1。数据字段不是固定长度。
2。数据字段位置可辨,行首及行中、行尾三种情况
例如:
11,222,33
2,12,90
23,235,3
11111111,0,10
33,222222,22
0,90,222222222

求助:请问按行首排序得sort命令如何?行中、行尾呢?

sort -n -t, +0 -1 +1 -2 +2 -3 filename

看CPU:
# ps auxwww |head -n 5
看虚存:
#ps av |sort +5 -r |head -n 5
看实存:
#ps av |sort +6 -r |head -n 5
看内存%:
# ps au |head -n 1; ps au |egrep -v "RSS"|sort +3 -r |head -n 5


du | sort -n

sort按照指定的分割符把输入分割。按照指定列对文件排序
sort [-t 分割符] [-r逆序] [+n指定用来排序的列] file
$sort -t: passwd
以:分割行。然后按照分类键0排序
$sort -t: -r passwd
排序求逆
$sort -t: +1 passwd
按照第二列的值进行排序
$sort -t: +2n passwd
按照第三列按数值大小排序
$sort -t: +0 -2 +3 passwd
按照域0排序,忽略域2,然后使用域3排序

cut截取子字串
1、cut -c char-list file
echo 2003060160910.dat | cut -c1-9
200306018
取出1-9个字符

2、cut -d 分隔符 -f field-list file
cut -d: -f1 passwd
alias
qmaild
qmaill
qmailp
qmailq
qmailr
qmails
vpopmail
按照:分隔,取出第一个字段

tr主要用于文字替换和压缩重复的字符
。大小写转换
echo abcdefg | tr "a-z" "A-Z"
ABCDEFG

。压缩空格
echo "ab cd ef g" | tr -s " "
ab cd ef g

。压缩空行
cat file | tr -s "\n"
posted @ 2006-11-27 21:59 剑落飘香 阅读(447) 评论(1) 编辑

2006年11月24日

通用线程:Awk 实例,第 1 部分
一种名称很奇特的优秀语言介绍

Daniel Robbins
总裁兼 CEO,Gentoo Technologies, Inc.
2000 年 12 月

转载自:IBM developerWorks 中国网站

 

 

内容:

 

 

Awk 是一种非常好的语言,同时有一个非常奇怪的名称。在本系列(共三篇文章)的第一篇文章中,Daniel Robbins 将使您迅速掌握 awk 编程技巧。随着本系列的进展,将讨论更高级的主题,最后将演示一个真正的高级 awk 演示程序。

 

 

捍卫 awk
在本系列文章中,我将使您成为精通 awk 的编码人员。我承认,awk 并没有一个非常好听且又非常“时髦”的名字。awk 的 GNU 版本(叫作 gawk)听起来非常怪异。那些不熟悉这种语言的人可能听说过 "awk", 并可能认为它是一组落伍且过时的混乱代码。它甚至会使最博学的 UNIX 权威陷于错乱的边缘(使他不断地发出 "kill -9!" 命令,就象使用咖啡机一样)。

的确,awk 没有一个动听的名字。但它是一种很棒的语言。awk 适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行需要特殊技巧程序设计。与某些语言不同,awk 的语法较为常见。它借鉴了某些语言的一些精华部分,如 C 语言、python 和 bash(虽然在技术上,awk 比 python 和 bash 早创建)。awk 是那种一旦学会了就会成为您战略编码库的主要部分的语言。

 

 

第一个 awk
让我们继续,开始使用 awk,以了解其工作原理。在命令行中输入以下命令

$ awk '{ print }' /etc/passwd

您将会见到 /etc/passwd 文件的内容出现在眼前。现在,解释 awk 做了些什么。调用 awk 时,我们指定 /etc/passwd 作为输入文件。执行 awk 时,它依次对 /etc/passwd 中的每一行执行 print 命令。所有输出都发送到 stdout,所得到的结果与与执行catting /etc/passwd完全相同。

现在,解释 { print } 代码块。在 awk 中,花括号用于将几块代码组合到一起,这一点类似于 C 语言。在代码块中只有一条 print 命令。在 awk 中,如果只出现 print 命令,那么将打印当前行的全部内容。

这里是另一个 awk 示例,它的作用与上例完全相同:

$ awk '{ print $0 }' /etc/passwd

awk 中,$0 变量表示整个当前行,所以 printprint $0 的作用完全一样。

如果您愿意,可以创建一个 awk 程序,让它输出与输入数据完全无关的数据。以下是一个示例:

$ awk '{ print "" }' /etc/passwd

只要将 "" 字符串传递给 print 命令,它就会打印空白行。如果测试该脚本,将会发现对于 /etc/passwd 文件中的每一行,awk 都输出一个空白行。再次说明, awk 对输入文件中的每一行都执行这个脚本。以下是另一个示例:

$ awk '{ print "hiya" }' /etc/passwd

运行这个脚本将在您的屏幕上写满 hiya。:)

 

 

多个字段
awk 非常善于处理分成多个逻辑字段的文本,而且让您可以毫不费力地引用 awk 脚本中每个独立的字段。以下脚本将打印出您的系统上所有用户帐户的列表:

$ awk -F":" '{ print $1 }' /etc/passwd

上例中,在调用 awk 时,使用 -F 选项来指定 ":" 作为字段分隔符。awk 处理 print $1 命令时,它会打印出在输入文件中每一行中出现的第一个字段。以下是另一个示例:

$ awk -F":" '{ print $1 $3 }' /etc/passwd

以下是该脚本输出的摘录:

halt7
operator11
root0
shutdown6
sync5
bin1
....etc.

如您所见,awk 打印出 /etc/passwd 文件的第一和第三个字段,它们正好分别是用户名和用户标识字段。现在,当脚本运行时,它并不理想 -- 在两个输出字段之间没有空格!如果习惯于使用 bash 或 python 进行编程,那么您会指望 print $1 $3 命令在两个字段之间插入空格。然而,当两个字符串在 awk 程序中彼此相邻时,awk 会连接它们但不在它们之间添加空格。以下命令会在这两个字段中插入空格:

$ awk -F":" '{ print $1 " " $3 }' /etc/passwd

以这种方式调用 print 时,它将连接 $1" " 和 $3,创建 可读的输出。当然,如果需要的话,我们还可以插入一些文本标签:

$ awk -F":" '{ print "username: " $1 "ttuid:" $3" }' /etc/passwd

这将产生以下输出:

username: halt          uid:7
username: operator      uid:11
username: root          uid:0
username: shutdown      uid:6
username: sync          uid:5
username: bin          uid:1
....etc.

外部脚本
将脚本作为命令行自变量传递给 awk 对于小的单行程序来说是非常简单的,而对于多行程序,它就比较复杂。您肯定想要在外部文件中撰写脚本。然后可以向 awk 传递 -f 选项,以向它提供此脚本文件:

$ awk -f myscript.awk myfile.in

将脚本放入文本文件还可以让您使用附加 awk 功能。例如,这个多行脚本与前面的单行脚本的作用相同,它们都打印出 /etc/passwd 中每一行的第一个字段:

BEGIN {
    FS=":"
}

{ print $1 }

这两个方法的差别在于如何设置字段分隔符。在这个脚本中,字段分隔符在代码自身中指定(通过设置 FS 变量),而在前一个示例中,通过在命令行上向 awk 传递 -F":" 选项来设置 FS。通常,最好在脚本自身中设置字段分隔符,只是因为这表示您可以少输入一个命令行自变量。我们将在本文的后面详细讨论 FS 变量。

 

 

BEGIN 和 END 块
通常,对于每个输入行,awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之执行初始化代码。对于这种情况,awk 允许您定义一个 BEGIN 块。我们在前一个示例中使用了 BEGIN 块。因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。

awk 还提供了另一个特殊块,叫作 END 块。awk 在处理了输入文件中的所有行之后执行这个块。通常,END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。

 

 

规则表达式和块
awk 允许使用规则表达式,根据规则表达式是否匹配当前行来选择执行独立代码块。以下示例脚本只输出包含字符序列
foo 的那些行:

/foo/ { print }

当然,可以使用更复杂的规则表达式。以下脚本将只打印包含浮点数的行:

/[0-9]+.[0-9]*/ { print }

表达式和块
还有许多其它方法可以选择执行代码块。我们可以将任意一种布尔表达式放在一个代码块之前,以控制何时执行某特定块。仅当对前面的布尔表达式求值为真时, awk 才执行代码块。以下示例脚本输出将输出其第一个字段等于
fred 的所有行中的第三个字段。如果当前行的第一个字段不等于 fredawk 将继续处理文件而不对当前行执行 print 语句:

$1 == "fred" { print $3 }

awk 提供了完整的比较运算符集合,包括 "=="、"<"、">"、"<="、">=" 和 "!="。另外,awk 还提供了 "~" 和 "!~" 运算符,它们分别表示“匹配”和“不匹配”。它们的用法是在运算符左边指定变量,在右边指定规则表达式。如果某一行的第五个字段包含字符序列 root, 那么以下示例将只打印这一行中的第三个字段:

$5 ~ /root/ { print $3 }

条件语句
awk 还提供了非常好的类似于 C 语言的
if 语句。如果您愿意,可以使用 if 语句重写前一个脚本:

{ 
    if ( $5 ~ /root/ ) {
        print $3
    }
}

这两个脚本的功能完全一样。第一个示例中,布尔表达式放在代码块外面。而在第二个示例中,将对每一个输入行执行代码块,而且我们使用 if 语句来选择执行 print 命令。这两个方法都可以使用,可以选择最适合脚本其它部分的一种方法。

以下是更复杂的 awk if 语句示例。可以看到,尽管使用了复杂、嵌套的条件语句,if 语句看上去仍与相应的 C 语言 if 语句一样:

{
    if ( $1 == "foo" ) {
        if ( $2 == "foo" ) {
            print "uno"
        } else {
            print "one"
        }
    } else if ($1 == "bar" ) {
        print "two"
    } else {
        print "three"
    }
}

使用 if 语句还可以将代码:

! /matchme/ { print $1 $3 $4 }

转换成:

{   
    if ( $0 !~ /matchme/ ) {
        print $1 $3 $4
    }
}

这两个脚本都只输出包含 matchme 字符序列的那些行。此外,还可以选择最适合您的代码的方法。它们的功能完全相同。

awk 还允许使用布尔运算符 "||"(逻辑与)和 "&&"(逻辑或),以便创建更复杂的布尔表达式:

( $1 == "foo" ) && ( $2 == "bar" ) { print } 

这个示例只打印第一个字段等于 foo 第二个字段等于 bar 的那些行。

 

 

数值变量!
至今,我们不是打印字符串、整行就是特定字段。然而,awk 还允许我们执行整数和浮点运算。通过使用数学表达式,可以很方便地编写计算文件中空白行数量的脚本。以下就是这样一个脚本:

BEGIN   { x=0 }
/^$/    { x=x+1 }
END     { print "I found " x " blank lines. :)" }

BEGIN 块中,将整数变量 x 初始化成零。然后,awk 每次遇到空白行时,awk 将执行 x=x+1 语句,递增 x。处理完所有行之后,执行 END 块,awk 将打印出最终摘要,指出它找到的空白行数量。

 

 

字符串化变量
awk 的优点之一就是“简单和字符串化”。我认为 awk 变量“字符串化”是因为所有 awk 变量在内部都是按字符串形式存储的。同时,awk 变量是“简单的”,因为可以对它执行数学操作,且只要变量包含有效数字字符串,awk 会自动处理字符串到数字的转换步骤。要理解我的观点,请研究以下这个示例:

x="1.01"
# We just set x to contain the *string* "1.01"
x=x+1
# We just added one to a *string*
print x
# Incidentally, these are comments :)

awk 将输出:

2.01

有趣吧!虽然将字符串值 1.01 赋值给变量 x,我们仍然可以对它加 一。但在 bash 和 python 中却不能这样做。首先,bash 不支持浮点运算。而且,如果 bash 有“字符串化”变量,它们并不“简单”;要执行任何数学操作,bash 要求我们将数字放到丑陋的 $( ) ) 结构中。如果使用 python,则必须在对 1.01 字符串执行任何数学运算之前,将它转换成浮点值。虽然这并不困难,但它仍是附加的步骤。如果使用 awk,它是全自动的,而那会使我们的代码又好又整洁。如果想要对每个输入行的第一个字段乘方并加一,可以使用以下脚本:

{ print ($1^2)+1 }

如果做一个小实验,就可以发现如果某个特定变量不包含有效数字,awk 在对数学表达式求值时会将该变量当作数字零处理。

 

 

众多运算符
awk 的另一个优点是它有完整的数学运算符集合。除了标准的加、减、乘、除,awk 还允许使用前面演示过的指数运算符 "^"、模(余数)运算符 "%" 和其它许多从 C 语言中借入的易于使用的赋值操作符。

这些运算符包括前后加减(i++--foo)、加/减/乘/除赋值运算符( a+=3b*=2c/=2.2d-=6.2)。不 仅如此 -- 我们还有易于使用的模/指数赋值运算符(a^=2b%=4)。

 

 

字段分隔符
awk 有它自己的特殊变量集合。其中一些允许调整 awk 的运行方式,而其它变量可以被读取以收集关于输入的有用信息。我们已经接触过这些特殊变量中的一个,FS。前面已经提到过,这个变量让您可以设置 awk 要查找的字段之间的字符序列。我们使用 /etc/passwd 作为输入时,将 FS 设置成 ":"。当这样做有问题时,我们还可以更灵活地使用 FS。

FS 值并没有被限制为单一字符;可以通过指定任意长度的字符模式,将它设置成规则表达式。如果正在处理由一个或多个 tab 分隔的字段,您可能希望按以下方式设置 FS:

FS="t+"

以上示例中,我们使用特殊 "+" 规则表达式字符,它表示“一个或多个前一字符”。

如果字段由空格分隔(一个或多个空格或 tab),您可能想要将 FS 设置成以下规则表达式:

FS="[[:space:]+]"

这个赋值表达式也有问题,它并非必要。为什么?因为缺省情况下,FS 设置成单一空格字符,awk 将这解释成表示“一个或多个空格或 tab”。在这个特殊示例中,缺省 FS 设置恰恰是您最想要的!

复杂的规则表达式也不成问题。即使您的记录由单词 "foo" 分隔,后面跟着三个数字,以下规则表达式仍允许对数据进行正确的分析:

FS="foo[0-9][0-9][0-9]"

字段数量
接着我们要讨论的两个变量通常并不是需要赋值的,而是用来读取以获取关于输入的有用信息。第一个是 NF 变量,也叫做“字段数量”变量。awk 会自动将该变量设置成当前记录中的字段数量。可以使用 NF 变量来只显示某些输入行:

NF == 3 { print "this particular record has three fields: " $0 }

当然,也可以在条件语句中使用 NF 变量,如下:

{   
    if ( NF > 2 ) {
        print $1 " " $2 ":" $3
    }
}

记录号
记录号 (NR) 是另一个方便的变量。它始终包含当前记录的编号(awk 将第一个记录算作记录号 1)。迄今为止,我们已经处理了每一行包含一个记录的输入文件。对于这些情况,NR 还会告诉您当前行号。然而,当我们在本系列以后部分中开始处理多行记录时,就不会再有这种情况,所以要注意!可以象使用 NF 变量一样使用 NR 来只打印某些输入行:

(NR < 10 ) || (NR > 100) { print "We are on record number 1-9 or 101+" }

另一个示例:

{
    #skip header
    if ( NR > 10 ) {
        print "ok, now for the real information!"
    }
}

awk 提供了适合各种用途的附加变量。

posted @ 2006-11-24 22:02 剑落飘香 阅读(289) 评论(0) 编辑
 

awk使用手册


什么是awk?

你可能对UNIX比较熟悉,但你可能对awk很陌生,这一点也不奇怪,的确,与其优秀的功能相比,awk还远没达到它应有的知名度。awk是什么?与其它大多数UNIX命令不同的是,从名字上看,我们不可能知道awk的功能:它既不是具有独立意义的英文单词,也不是几个相关单词的缩写。事实上,awk是三个人名的缩写,他们是:Aho、(Peter)Weinberg和(Brain)Kernighan。正是这三个人创造了awk---一个优秀的样式扫描与处理工具。

AWK的功能是什么?与sed和grep很相似,awk是一种样式扫描与处理工具。但其功能却大大强于sed和grep。awk提供了极其强大的功能:它几乎可以完成grep和sed所能完成的全部工作,同时,它还可以可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上,awk的确拥有自己的语言:awk程序设计语言,awk的三位创建者已将它正式定义为:样式扫描和处理语言。

为什么使用awk?

即使如此,你也许仍然会问,我为什么要使用awk?

使用awk的第一个理由是基于文本的样式扫描和处理是我们经常做的工作,awk所做的工作有些象数据库,但与数据库不同的是,它处理的是文本文件,这些文件没有专门的存储格式,普通的人们就能编辑、阅读、理解和处理它们。而数据库文件往往具有特殊的存储格式,这使得它们必须用数据库处理程序来处理它们。既然这种类似于数据库的处理工作我们经常会遇到,我们就应当找到处理它们的简便易行的方法,UNIX有很多这方面的工具,例如sed 、grep、sort以及find等等,awk是其中十分优秀的一种。

使用awk的第二个理由是awk是一个简单的工具,当然这是相对于其强大的功能来说的。的确,UNIX有许多优秀的工具,例如UNIX天然的开发工具C语言及其延续C++就非常的优秀。但相对于它们来说,awk完成同样的功能要方便和简捷得多。这首先是因为awk提供了适应多种需要的解决方案:从解决简单问题的awk命令行到复杂而精巧的awk程序设计语言,这样做的好处是,你可以不必用复杂的方法去解决本来很简单的问题。例如,你可以用一个命令行解决简单的问题,而C不行,即使一个再简单的程序,C语言也必须经过编写、编译的全过程。其次,awk本身是解释执行的,这就使得awk程序不必经过编译的过程,同时,这也使得它与shell script程序能够很好的契合。最后,awk本身较C语言简单,虽然awk吸收了C语言很多优秀的成分,熟悉C语言会对学习awk有很大的帮助,但awk本身不须要会使用C语言——一种功能强大但需要大量时间学习才能掌握其技巧的开发工具。

使用awk的第三个理由是awk是一个容易获得的工具。与C和C++语言不同,awk只有一个文件(/bin/awk),而且几乎每个版本的UNIX都提供各自版本的awk,你完全不必费心去想如何获得awk。但C语言却不是这样,虽然C语言是UNIX天然的开发工具,但这个开发工具却是单独发行的,换言之,你必须为你的UNIX版本的C语言开发工具单独付费(当然使用D版者除外),获得并安装它,然后你才可以使用它。

基于以上理由,再加上awk强大的功能,我们有理由说,如果你要处理与文本样式扫描相关的工作,awk应该是你的第一选择。在这里有一个可遵循的一般原则:如果你用普通的shell工具或shell script有困难的话,试试awk,如果awk仍不能解决问题,则便用C语言,如果C语言仍然失败,则移至C++。

awk的调用方式

前面曾经说过,awk提供了适应多种需要的不同解决方案,它们是:

一、awk命令行,你可以象使用普通UNIX命令一样使用awk,在命令行中你也可以使用awk程序设计语言,虽然awk支持多行的录入,但是录入长长的命令行并保证其正确无误却是一件令人头疼的事,因此,这种方法一般只用于解决简单的问题。当然,你也可以在shell script程序中引用awk命令行甚至awk程序脚本。

二、使用-f选项调用awk程序。awk允许将一段awk程序写入一个文本文件,然后在awk命令行中用-f选项调用并执行这段程序。具体的方法我们将在后面的awk语法中讲到。

三、利用命令解释器调用awk程序:利用UNIX支持的命令解释器功能,我们可以将一段awk程序写入文本文件,然后在它的第一行加上:
#!/bin/awk -f
并赋予这个文本文件以执行的权限。这样做之后,你就可以在命令行中用类似于下面这样的方式调用并执行这段awk程序了。

$awk脚本文本名 待处理文件

awk的语法:

与其它UNIX命令一样,awk拥有自己的语法:

awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...]

参数说明:

-F re:允许awk更改其字段分隔符。

parameter: 该参数帮助为不同的变量赋值。

'prog': awk的程序语句段。这个语句段必须用单拓号:'和'括起,以防被shell解释。这个程序语句段的标准形式为:

'pattern {action}'

其中pattern参数可以是egrep正则表达式中的任何一个,它可以使用语法/re/再加上一些样式匹配技巧构成。与sed类似,你也可以使用","分开两样式以选择某个范围。关于匹配的细节,你可以参考附录,如果仍不懂的话,找本UNIX书学学grep和sed(本人是在学习ed时掌握匹配技术的)。action参数总是被大括号包围,它由一系统awk语句组成,各语句之间用";"分隔。awk解释它们,并在pattern给定的样式匹配的记录上执行其操作。与shell类似,你也可以使用“#”作为注释符,它使“#”到行尾的内容成为注释,在解释执行时,它们将被忽略。你可以省略pattern和action之一,但不能两者同时省略,当省略pattern时没有样式匹配,表示对所有行(记录)均执行操作,省略action时执行缺省的操作——在标准输出上显示。

-f progfile:允许awk调用并执行progfile指定有程序文件。progfile是一个文本文件,他必须符合awk的语法。

in_file:awk的输入文件,awk允许对多个输入文件进行处理。值得注意的是awk不修改输入文件。如果未指定输入文件,awk将接受标准输入,并将结果显示在标准输出上。awk支持输入输出重定向。

awk的记录、字段与内置变量:

前面说过,awk处理的工作与数据库的处理方式有相同之处,其相同处之一就是awk支持对记录和字段的处理,其中对字段的处理是grep和sed不能实现的,这也是awk优于二者的原因之一。在awk中,缺省的情况下总是将文本文件中的一行视为一个记录,而将一行中的某一部分作为记录中的一个字段。为了操作这些不同的字段,awk借用shell的方法,用$1,$2,$3...这样的方式来顺序地表示行(记录)中的不同字段。特殊地,awk用$0表示整个行(记录)。不同的字段之间是用称作分隔符的字符分隔开的。系统默认的分隔符是空格。awk允许在命令行中用-F re的形式来改变这个分隔符。事实上,awk用一个内置的变量FS来记忆这个分隔符。awk中有好几个这样的内置变量,例如,记录分隔符变量RS、当前工作的记录数NR等等,本文后面的附表列出了全部的内置变量。这些内置的变量可以在awk程序中引用或修改,例如,你可以利用NR变量在模式匹配中指定工作范围,也可以通过修改记录分隔符RS让一个特殊字符而不是换行符作为记录的分隔符。

例:显示文本文件myfile中第七行到第十五行中以字符%分隔的第一字段,第三字段和第七字段:

awk -F % 'NR==7,NR==15 {printf $1 $3 $7}'

awk的内置函数

awk之所以成为一种优秀的程序设计语言的原因之一是它吸收了某些优秀的程序设计语言(例如C)语言的许多优点。这些优点之一就是内置函数的使用,awk定义并支持了一系列的内置函数,由于这些函数的使用,使得awk提供的功能更为完善和强大,例如,awk使用了一系列的字符串处理内置函数(这些函数看起来与C语言的字符串处理函数相似,其使用方式与C语言中的函数也相差无几),正是由于这些内置函数的使用,使awk处理字符串的功能更加强大。本文后面的附录中列有一般的awk所提供的内置函数,这些内置函数也许与你的awk版本有些出入,因此,在使用之前,最好参考一下你的系统中的联机帮助。

作为内置函数的一个例子,我们将在这里介绍awk的printf函数,这个函数使得awk与c语言的输出相一致。实际上,awk中有许多引用形式都是从C语言借用过来的。如果你熟悉C语言,你也许会记得其中的printf函数,它提供的强大格式输出功能曾经带我们许多的方便。幸运的是,我们在awk中又和它重逢了。awk中printf几乎与C语言中一模一样,如果你熟悉C语言的话,你完全可以照C语言的模式使用awk中的printf。因此在这里,我们只给出一个例子,如果你不熟悉的话,请随便找一本C语言的入门书翻翻。

例:显示文件myfile中的行号和第3字段:

$awk '{printf"%03d%s\n",NR,$1}' myfile

在命令行使用awk

按照顺序,我们应当讲解awk程序设计的内容了,但在讲解之前,我们将用一些例子来对前面的知识进行回顾,这些例子都是在命令行中使用的,由此我们可以知道在命令行中使用awk是多么的方便。这样做的原因一方面是为下面的内容作铺垫,另一方面是介绍一些解决简单问题的方法,我们完全没有必要用复杂的方法来解决简单的问题----既然awk提供了较为简单的方法的话。

例:显示文本文件mydoc匹配(含有)字符串"sun"的所有行。

$awk '/sun/{print}' mydoc

由于显示整个记录(全行)是awk的缺省动作,因此可以省略action项。

$awk '/sun/' mydoc

例:下面是一个较为复杂的匹配的示例:

$awk '/[Ss]un/,/[Mm]oon/ {print}' myfile

它将显示第一个匹配Sun或sun的行与第一个匹配Moon或moon的行之间的行,并显示到标准输出上。

例:下面的示例显示了内置变量和内置函数length()的使用:

$awk 'length($0)>80 {print NR}' myfile

该命令行将显示文本myfile中所有超过80个字符的行号,在这里,用$0表示整个记录(行),同时,内置变量NR不使用标志符'$'。

例:作为一个较为实际的例子,我们假设要对UNIX中的用户进行安全性检查,方法是考察/etc下的passwd文件,检查其中的passwd字段(第二字段)是否为"*",如不为"*",则表示该用户没有设置密码,显示出这些用户名(第一字段)。我们可以用如下语句实现:

#awk -F: '$2=="" {printf("%s no password!\n",$1' /etc/passwd

在这个示例中,passwd文件的字段分隔符是“:”,因此,必须用-F:来更改默认的字段分隔符,这个示例中也涉及到了内置函数printf的使用。

awk的变量

如同其它程序设计语言一样,awk允许在程序语言中设置变量,事实上,提供变量的功能是程序设计语言的其本要求,不提供变量的程序设计语言本人还从未见过。

awk提供两种变量,一种是awk内置的变量,这前面我们已经讲过,需要着重指出的是,与后面提到的其它变量不同的是,在awk程序中引用内置变量不需要使用标志符"$"(回忆一下前面讲过的NR的使用)。awk提供的另一种变量是自定义变量。awk允许用户在awk程序语句中定义并调用自已的变量。当然这种变量不能与内置变量及其它awk保留字相同,在awk中引用自定义变量必须在它前面加上标志符"$"。与C语言不同的是,awk中不需要对变量进行初始化,awk根据其在awk中第一次出现的形式和上下文确定其具体的数据类型。当变量类型不确定时,awk默认其为字符串类型。这里有一个技巧:如果你要让你的awk程序知道你所使用的变量的明确类型,你应当在在程序中给它赋初值。在后面的实例中,我们将用到这一技巧。

运算与判断:

作为一种程序设计语言所应具有的特点之一,awk支持多种运算,这些运算与C语言提供的几本相同:如+、-、*、/、%等等,同时,awk也支持C语言中类似++、--、+=、-=、=+、=-之类的功能,这给熟悉C语言的使用者编写awk程序带来了极大的方便。作为对运算功能的一种扩展,awk还提供了一系列内置的运算函数(如log、sqr、cos、sin等等)和一些用于对字符串进行操作(运算)的函数(如length、substr等等)。这些函数的引用大大的提高了awk的运算功能。

作为对条件转移指令的一部分,关系判断是每种程序设计语言都具备的功能,awk也不例外。awk中允许进行多种测试,如常用的==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、>=(小于等于)等等,同时,作为样式匹配,还提供了~(匹配于)和!~(不匹配于)判断。

作为对测试的一种扩充,awk也支持用逻辑运算符:!(非)、&&(与)、||(或)和括号()进行多重判断,这大大增强了awk的功能。本文的附录中列出了awk所允许的运算、判断以及操作符的优先级。

awk的流程控制

流程控制语句是任何程序设计语言都不能缺少的部分。任何好的语言都有一些执行流程控制的语句。awk提供的完备的流程控制语句类似于C语言,这给我们编程带来了极大的方便。

1、BEGIN和END:

在awk中两个特别的表达式,BEGIN和END,这两者都可用于pattern中(参考前面的awk语法),提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。任何在BEGIN之后列出的操作(在{}内)将在awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。

例:累计销售文件xs中的销售金额(假设销售金额在记录的第三字段):

$awk
>'BEGIN { FS=":";print "统计销售金额";total=0}
>{print $3;total=total+$3;}
>END {printf "销售金额总计:%.2f",total}' sx
(注:>是shell提供的第二提示符,如要在shell程序awk语句和awk语言中换行,则需在行尾加反斜杠\)

在这里,BEGIN预置了内部变量FS(字段分隔符)和自定义变量total,同时在扫描之前显示出输出行头。而END则在扫描完成后打印出总合计。

2、流程控制语句
awk提供了完备的流程控制语句,其用法与C语言类似。下面我们一一加以说明:

2.1、if...else语句:

格式:
if(表达式)
语句1
else
语句2

格式中"语句1"可以是多个语句,如果你为了方便awk判断也方便你自已阅读,你最好将多个语句用{}括起来。awk分枝结构允许嵌套,其格式为:

if(表达式1)
{if(表达式2)
语句1
else
语句2
}
语句3
else {if(表达式3)
语句4
else
语句5
}
语句6

当然实际操作过程中你可能不会用到如此复杂的分枝结构,这里只是为了给出其样式罢了。

2.2、while语句

格式为:

while(表达式)
语句

2.3、do-while语句

格式为:

do
{
语句
}while(条件判断语句)

2.4、for语句

格式为:

for(初始表达式;终止条件;步长表达式)
{语句}

在awk的 while、do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句来退出。break中断当前正在执行的循环并跳到循环外执行下一条语句。continue从当前位置跳到循环开始处执行。对于exit的执行有两种情况:当exit语句不在END中时,任何操作中的exit命令表现得如同到了文件尾,所有模式或操作执行将停止,END模式中的操作被执行。而出现在END中的exit将导致程序终止。

例:为了

awk中的自定义函数

定义和调用用户自己的函数是几乎每个高级语言都具有的功能,awk也不例外,但原始的awk并不提供函数功能,只有在nawk或较新的awk版本中才可以增加函数。

函数的使用包含两部分:函数的定义与函数调用。其中函数定义又包括要执行的代码(函数本身)和从主程序代码传递到该函数的临时调用。

awk函数的定义方法如下:

function 函数名(参数表){
函数体
}

在gawk中允许将function省略为func,但其它版本的awk不允许。函数名必须是一个合法的标志符,参数表中可以不提供参数(但在调用函数时函数名后的一对括号仍然是不可缺少的),也可以提供一个或多个参数。与C语言相似,awk的参数也是通过值来传递的。

在awk中调用函数比较简单,其方法与C语言相似,但awk比C语言更为灵活,它不执行参数有效性检查。换句话说,在你调用函数时,可以列出比函数预计(函数定义中规定)的多或少的参数,多余的参数会被awk所忽略,而不足的参数,awk将它们置为缺省值0或空字符串,具体置为何值,将取决于参数的使用方式。

awk函数有两种返回方式:隐式返回和显式返回。当awk执行到函数的结尾时,它自动地返回到调用程序,这是函数是隐式返回的。如果需要在结束之前退出函数,可以明确地使用返回语句提前退出。方法是在函数中使用形如:return 返回值 格式的语句。

例:下面的例子演示了函数的使用。在这个示例中,定义了一个名为print_header的函数,该函数调用了两个参数FileName和PageNum,FileName参数传给函数当前使用的文件名,PageNum参数是当前页的页号。这个函数的功能是打印(显示)出当前文件的文件名,和当前页的页号。完成这个功能后,这个函数将返回下一页的页号。

nawk
>'BEGIN{pageno=1;file=FILENAME
>pageno=print_header(file,pageno);#调用函数print_header
>printf("当前页页号是:%d\n",pageno);
>}

>#定义函数print_header
>function print_header(FileName,PageNum){
>printf("%s %d\n",FileName,PageNum); >PageNum++;return PageNUm;
>}
>}' myfile

执行这个程序将显示如下内容:

myfile 1
当前页页号是:2

awk高级输入输出

1.读取下一条记录:

awk的next语句导致awk读取下一个记录并完成模式匹配,然后立即执行相应的操作。通常它用匹配的模式执行操作中的代码。next导致这个记录的任何额外匹配模式被忽略。

2.简单地读取一条记录

awk的 getline语句用于简单地读取一条记录。如果用户有一个数据记录类似两个物理记录,那么getline将尤其有用。它完成一般字段的分离(设置字段变量$0 FNR NF NR)。如果成功则返回1,失败则返回0(到达文件尾)。如果需简单地读取一个文件,则可以编写以下代码:

例:示例getline的使用

{while(getline==1)
{
#process the inputted fields
}
}

也可以使getline保存输入数据在一个字段中,而不是通过使用getline variable的形式处理一般字段。当使用这种方式时,NF被置成0,FNR和NR被增值。

用户也可以使用getline<"filename"方式从一个给定的文件中输入数据,而不是从命令行所列内容输入数据。此时,getline将完成一般字段分离(设置字段变量$0和NF)。如果文件不存在,返回-1,成功,返回1,返回0表示失败。用户可以从给定文件中读取数据到一个变量中,也可以用stdin(标准输入设备)或一个包含这个文件名的变量代替filename。值得注意的是当使用这种方式时不修改FNR和NR。

另一种使用getline语句的方法是从UNIX命令接受输入,例如下面的例子:

例:示例从UNIX命令接受输入

{while("who -u"|getline)
{
#process each line from the who command
}
}

当然,也可以使用如下形式:

"command" | getline variable

3.关闭文件:

awk中允许在程序中关闭一个输入或输出文件,方法是使用awk的close语句。

close("filename")

filename可以是getline打开的文件(也可以是stdin,包含文件名的变量或者getline使用的确切命令)。或一个输出文件(可以是stdout,包含文件名的变量或使用管道的确切命令)。

4.输出到一个文件:

awk中允许用如下方式将结果输出到一个文件:

printf("hello word!\n")>"datafile"

printf("hello word!\n")>>"datafile"

5.输出到一个命令

awk中允许用如下方式将结果输出到一个命令:

printf("hello word!\n")|"sort-t','"

awk与shell script混合编程

因为awk可以作为一个shell命令使用,因此awk能与shell批处理程序很好的融合在一起,这给实现awk与shell程序的混合编程提供了可能。实现混合编程的关键是awk与shell script之间的对话,换言之,就是awk与shell script之间的信息交流:awk从shell script中获取所需的信息(通常是变量的值)、在awk中执行shell命令行、shell script将命令执行的结果送给awk处理以及shell script读取awk的执行结果等等。

1.awk读取Shell script程序变量

在awk中我们可以通过“'$变量名'”的方式读取sell scrpit程序中的变量。

例:在下面的示例中,我们将读取sell scrpit程序中的变量Name,该变量存放的是文本myfile的撰写者,awk将打印出这个人名。

$cat writename
:
# @(#)
#
.
.
.
Name="张三" nawk 'BEGIN {name="'Name'";\ printf("\t%s\t撰写者%s\n",FILENAME,name");}\
{...}END{...}' myfile
.
.
.

2.将shell命令的执行结果送给awk处理

作为信息传送的一种方法,我们可以将一条shell命令的结果通过管道线(|)传递给awk处理:

例:示例awk处理shell命令的执行结果

$who -u | awk '{printf("%s正在执行%s\n",$2,$1)}'

该命令将打印出注册终端正在执行的程序名。

3.shell script程序读awk的执行结果

为了实现shell script程序读取awk执行的结果,我们可以采取一些特殊的方法,例如我们可以用变量名=`awk语句`的形式将awk执行的结果存放入一个shell script变量。当然也可以用管道线的方法将awk执行结果传递给shell script程序处理。

例:作为传送消息的机制之一,UNIX提供了一个向其所有用户传送消息的命令wall(意思是write to all写给所有用户),该命令允许向所有工作中的用户(终端)发送消息。为此,我们可以通过一段shell批处理程序wall.shell来模拟这一程序(事实上比较老的版本中wall就是一段shell批处理程序:

$cat wall.shell
:
# @(#) wall.shell:发送消息给每个已注册终端
#
cat >/tmp/$$
#用户录入消息文本 who -u | awk '{print $2}' | while read tty
do
cat /tmp/$$>$tty
done

在这个程序里,awk接受who -u命令的执行结果,该命令打印出所有已注册终端的信息,其中第二个字段是已注册终端的设备名,因此用awk命令析出该设备名,然后用while read tty语句循环读出这些文件名到变量(shell script变量)tty中,作为信息传送的终结地址。

4.在awk中执行shell命令行----嵌入函数system()

system()是一个不适合字符或数字类型的嵌入函数,该函数的功能是处理作为参数传递给它的字符串。system对这个参数的处理就是将其作为命令处理,也就是说将其当作命令行一样加以执行。这使得用户在自己的awk程序需要时可以灵活地执行命令或脚本。

例:下面的程序将使用system嵌入函数打印用户编制好的报表文件,这个文件存放在名为myreport.txt的文件中。为简约起见,我们只列出了其END部分:

.
.
.
END {close("myreport.txt");system("lp myreport.txt");}

在这个示例中,我们首先使用close语句关闭了文件myreport.txt文件,然后使用system嵌入函数将myreport.txt送入打印机打印。

写到这里,我不得不跟朋友们说再见了,实在地说,这些内容仍然是awk的初步知识,电脑永远是前进的科学,awk也不例外,本篇所能做的只是在你前行的漫漫长途中铺平一段小小开端,剩下的路还得靠你自己去走。老实说,如果本文真能给你前行的路上带来些许的方便,那本人就知足了!

如对本篇有任何疑问,请E-mail To:Chizlong@yeah.net或到主页http://chizling.yeah.net中留言。


附录:

1.awk的常规表达式元字符

\ 换码序列
^ 在字符串的开头开始匹配
$ 在字符串的结尾开始匹配
. 与任何单个字符串匹配
[ABC] 与[]内的任一字符匹配
[A-Ca-c] 与A-C及a-c范围内的字符匹配(按字母表顺序)
[^ABC] 与除[]内的所有字符以外的任一字符匹配
Desk|Chair 与Desk和Chair中的任一个匹配
[ABC][DEF] 关联。与A、B、C中的任一字符匹配,且其后要跟D、E、F中的任一个字符。
* 与A、B或C中任一个出现0次或多次的字符相匹配
+ 与A、B或C中任何一个出现1次或多次的字符相匹配
? 与一个空串或A、B或C在任何一个字符相匹配
(Blue|Black)berry 合并常规表达式,与Blueberry或Blackberry相匹配

2.awk算术运算符

运算符 用途
------------------
x^y x的y次幂
x**y 同上
x%y 计算x/y的余数(求模)
x+y x加y
x-y x减y
x*y x乘y
x/y x除y
-y 负y(y的开关符号);也称一目减
++y y加1后使用y(前置加)
y++ 使用y值后加1(后缀加)
--y y减1后使用y(前置减)
y-- 使用后y减1(后缀减)
x=y 将y的值赋给x
x+=y 将x+y的值赋给x
x-=y 将x-y的值赋给x
x*=y 将x*y的值赋给x
x/=y 将x/y的值赋给x x%=y 将x%y的值赋给x
x^=y 将x^y的值赋给x
x**=y 将x**y的值赋给x

3.awk允许的测试:

操作符 含义

x==y x等于y
x!=y x不等于y
x>y x大于y
x>=y x大于或等于y
x<y x小于y
x<=y x小于或等于y?
x~re x匹配正则表达式re?
x!~re x不匹配正则表达式re?

4.awk的操作符(按优先级升序排列)

= 、+=、 -=、 *= 、/= 、 %=
||
&&
> >= < <= == != ~ !~
xy (字符串连结,'x''y'变成"xy")
+ -
* / %
++ --

5.awk内置变量(预定义变量)

说明:表中v项表示第一个支持变量的工具(下同):A=awk,N=nawk,P=POSIX awk,G=gawk

V 变量 含义 缺省值
--------------------------------------------------------
N ARGC 命令行参数个数
G ARGIND 当前被处理文件的ARGV标志符
N ARGV 命令行参数数组
G CONVFMT 数字转换格式 %.6g
P ENVIRON UNIX环境变量
N ERRNO UNIX系统错误消息
G FIELDWIDTHS 输入字段宽度的空白分隔字符串
A FILENAME 当前输入文件的名字
P FNR 当前记录数
A FS 输入字段分隔符 空格
G IGNORECASE 控制大小写敏感0(大小写敏感)
A NF 当前记录中的字段个数
A NR 已经读出的记录数
A OFMT 数字的输出格式 %.6g
A OFS 输出字段分隔符 空格
A ORS 输出的记录分隔符 新行
A RS 输入的记录他隔符 新行
N RSTART 被匹配函数匹配的字符串首
N RLENGTH 被匹配函数匹配的字符串长度
N SUBSEP 下标分隔符 "\034"

6.awk的内置函数

V 函数 用途或返回值
------------------------------------------------
N gsub(reg,string,target) 每次常规表达式reg匹配时替换target中的string
N index(search,string) 返回string中search串的位置
A length(string) 求串string中的字符个数
N match(string,reg) 返回常规表达式reg匹配的string中的位置
N printf(format,variable) 格式化输出,按format提供的格式输出变量variable。
N split(string,store,delim) 根据分界符delim,分解string为store的数组元素
N sprintf(format,variable) 返回一个包含基于format的格式化数据,variables是要放到串中的数据
G strftime(format,timestamp) 返回一个基于format的日期或者时间串,timestmp是systime()函数返回的时间
N sub(reg,string,target) 第一次当常规表达式reg匹配,替换target串中的字符串
A substr(string,position,len) 返回一个以position开始len个字符的子串
P totower(string) 返回string中对应的小写字符
P toupper(string) 返回string中对应的大写字符
A atan(x,y) x的余切(弧度)
N cos(x) x的余弦(弧度)
A exp(x) e的x幂
A int(x) x的整数部分
A log(x) x的自然对数值
N rand() 0-1之间的随机数
N sin(x) x的正弦(弧度)
A sqrt(x) x的平方根
A srand(x) 初始化随机数发生器。如果忽略x,则使用system()
G system() 返回自1970年1月1日以来经过的时间(按秒计算) 

posted @ 2006-11-24 21:53 剑落飘香 阅读(126) 评论(0) 编辑

2006年11月23日

#!/bin/bash
                                                                                                                                              
                                                                                                                                              
echo "*****************"
echo       欢迎使用
echo "1.添加用户"
echo "2.退出操作"
echo "*****************"
echo "请选择:"
read again
                                                                                                                                              
while [ $again -eq 1 ]
do
echo ==============================
echo "请输入您希望创建的用户的个数";read num
cd /home
let x=1
while [ $x -le $num ]
do
echo ====================
echo "请输入第$x个用户名";read name
useradd $name
echo ========================
echo "请输入第$x个用户的密码"
passwd $name
let x=x+1
done
echo "*****************"
echo "1.继续添加用户"
echo "2.退出操作"
echo "*****************"
echo "请选择:"
read again
done
echo =============================
echo Thank for use, Goodbye ^_^
echo =============================


posted @ 2006-11-23 13:06 剑落飘香 阅读(64) 评论(0) 编辑
 

成批添加用户账户

  • 创建脚本addusers,内容为:

    #!/bin/bash
        echo -n " Give me the name of the file containing user data..."
        read file[1]
        [ ! -f $file ] && ( echo " '$file' does not exist..."; exit 1 )
        while read username[2]
        do useradd $username >/dev/null 2>&1[3]
        if [ $? -ne 0 ]
        then echo " Fail to create an account with name=$username..."
        else echo 'redhat' | passwd --stdin $username >/dev/null 2>&1[4]
        fi
        done < $file
  • 创建用户名数据文件users,内容为:

    user101
        user102
        user103
        user104
  • 执行脚本创建多个用户

    # bash addusers
        Give me the name of the file containing user data... users[5]


[1] 读取用户名数据文件。

[2] 若未读取到数据文件尾,则读取一个用户名。

[3] 创建用户。

[4] 若创建用户成功,则为其设置初始口令为redhat。

[5] 输入用户名数据文件的名称。

posted @ 2006-11-23 10:47 剑落飘香 阅读(136) 评论(0) 编辑

2006年11月22日

摘要: #!/bin/shecho "大九九乘法表"for i in 1 2 3 4 5 6 7 8 9dofor j in 1 2 3 4 5 6 7 8 9dolet "sum=i*j"printf "$i*$j=$sum \t"doneprintf "\n"done#!/bin/shecho "小九九乘法表"for i in 1 2 3 4 5 6 7 8 9doj=1while [ $j -le ...阅读全文
posted @ 2006-11-22 17:31 剑落飘香 阅读(349) 评论(0) 编辑
 
Copyright © 剑落飘香 Powered by: 博客园 模板提供:沪江博客