星期一, 十月 26, 2009

sed替换网址的解决方法

替换/时----
比如替换///成:::
可以用sed 's/\/\/\//:::/g' 即在前面加一个反斜杆
当然这样不友好
我们更喜欢
sed '_///_:::_g' 即把分隔符换了 换成其他符号如: 都可以的

替换一长串莫名字符,比如把以下内容//到:之间都替换成@
//abcd19388102738234:
//ijsh12398097324:
//pppppafasfae1231231:
可以用sed 's_//.*:_@_g'

sed对同一文件替换导致文件清空的原因分析

做文件替换的时候我们经常想仅用一个文件,直接替换内容,但是这个在sed里面是不可以的。

sed 's/old/new/g' filename >filename (WRONG)

因为在执行前遇到> 重定向符号,unix先把文件清空,于是没有内容。


sed替换同一文件,必须用一个临时文件。

sed 's/old/new/g' filename >filename_tmp

mv filename_tmp filename (CORRECT)


参考:

When you use redirection, the shell truncates the file before executing the command, and sed will see an empty file. You must redirect the output to a different file and then move or copy the new file over the old one, e.g.:

Pasted from <http://unix.ittoolbox.com/groups/technical-functional/shellscript-l/trying-to-change-a-file-with-sed-2242269>

星期三, 八月 12, 2009

GROUP BY, HAVING, SUM, AVG, and COUNT(*) 转载

Welcome to the Database Programmer!

Good programming skills do not lead magically to good database skills. Masterful use of the database requires knowledge of the database in its own terms. Step 1 is knowing your table design patterns, and Step 2 is knowing how to fashion efficient queries. Learning how to code good queries can lead to faster performance and better application code.

There is a new entry in this series every Monday morning, and the Complete Table of Contents is here.

Aggregation

You can use a SQL SELECT to aggregate data. Aggregation combines rows together and performs some operation on their combined values. Very common aggregations are COUNT, SUM, and AVG.

The simplest use of aggregations is to examine an entire table and pull out only the aggregations, with no other columns specified. Consider this SQL:

SELECT COUNT(*) as cnt       ,SUM(sale_amount) as sum       ,AVG(sale_amount) as avg   FROM orders 

If you have a very small sales order table, say about 7 rows, like this:

ORDER |  DATE      | STATE | SALE_AMOUNT ------+------------+-------+-------------  1234 | 2007-11-01 | NY    |       10.00  1235 | 2007-12-01 | TX    |       15.00  1236 | 2008-01-01 | CA    |       20.00  1237 | 2008-02-01 | TX    |       25.00  1238 | 2008-03-01 | CA    |       30.00  1237 | 2008-04-01 | NY    |       35.00  1238 | 2008-05-01 | NY    |       40.00 

Then the simple query above produces a one-row output:

CNT  | SUM  | AVG -----+------+-----   7  | 175  |  25 

Some Notes on The Syntax

When we use COUNT(*) we always put the asterisk inside.

I have used the "as SUM" to specify a column name of the output. Without that I will get whatever the database server decides to call it, which will vary from platform to platform, so it is a good idea to learn to use the "AS" clause. Some folks would frown at using "SUM" as the name, since that is the name of the function and might be confusing, but I think we're all big kids and we can probably handle it.

The WHERE Clause Does What You Think

If you want to get just the sales from New York state, you can put a WHERE clause in:

SELECT COUNT(*) as cnt       ,SUM(sale_amount) as sum       ,AVG(sale_amount) as avg   FROM orders  WHERE state = 'NY' 

...and you will get only the results for NY:

CNT | SUM  | AVG ----+------+----------   3 |  85  |  28.33333 

Notice of course that the average has a repeating decimal. Most databases have a ROUND function of some sort, so I can correct that with:

SELECT COUNT(*) as cnt       ,SUM(sale_amount) as sum       ,ROUND(AVG(sale_amount),0) as avg   FROM orders  WHERE state = 'NY' 

The Fun Begins With GROUP BY

The query above is fine, but it would be very laborious if you had to issue the query (or write a program to do it) for every possible state. The answer is the GROUP BY clause. The GROUP BY clause says that the aggregations should be performed for the distinct values of a column or columns. It looks like this:

SELECT state,       ,COUNT(*) as cnt       ,SUM(sale_amount) as sum       ,ROUND(AVG(sale_amount),0) as avg   FROM orders  GROUP BY state 

Which gives us this result:

STATE | CNT | SUM  | AVG ------+-----+------+---- NY    |  3  |  85  |  28 TX    |  2  |  40  |  20 CA    |  2  |  50  |  25   

Note that if you try to include a column that you are not grouping on, such as zip code, most database servers will reject the query because there may be different values of zip code for the same value of state, and they have no way to know which one to pick for a given value of state.

HAVING Clause is Like WHERE after GROUP BY

The HAVING clause lets us put a filter on the results after the aggregation has taken place. If your Sales Manager wants to know which states have an average sale amount of $25.00 or more. Now our query looks like this:

SELECT state,       ,COUNT(*) as cnt       ,SUM(sale_amount) as sum       ,ROUND(AVG(sale_amount),0) as avg   FROM orders  GROUP BY state HAVING AVG(sale_amount) >= 25 

Which gives us this result, notice that Texas is now missing, as they were just not selling big enough orders (sorry 'bout that Rhonda).

STATE | CNT | SUM  | AVG ------+-----+------+---- NY    |  3  |  85  |  28 CA    |  2  |  50  |  25   

The Hat Trick: All Three

You can pull some pretty nice results out of a database in a single query if you know how to combine the WHERE, GROUP BY, and HAVING. If you have ever worked with a Sales Manager, you know they constantly want to know strange numbers, so let's say our Sales Manager says, "Can you tell me the average order size by state for all orders greater than 20? And don't bother with any average less 30.00" We say, "Sure, don't walk away, I'll print it out right now."

SELECT state       ,COUNT(*)       ,SUM(sale_amount) as sum       ,ROUND(AVG(sale_amount) as avg   FROM orders  WHERE sale_amount > 20  GROUP BY state HAVING avg(sale_amount) >= 30 

How to Do a Weighted Average

Consider the case of a table that lists test, homework and quiz scores for the students in a certain course. Each particular score is worth a certain percentage of a student's grade, and the teacher wants the computer to calculate each student's file score. If the table looks like:

STUDENT     | WEIGHT | SCORE ------------+--------+------- NIRGALAI    |     40 |    90 NIRGALAI    |     35 |    95 NIRGALAI    |     25 |    85 JBOONE      |     40 |    80 JBOONE      |     35 |    95 JBOONE      |     25 |    70 PCLAYBORNE  |     40 |    70 PCLAYBORNE  |     35 |    80 PCLAYBORNE  |     25 |    90 

Then we can accomplish this in one pull like so:

SELECT student       ,SUM(weight * score) / 100 as final   FROM scores  GROUP BY student 

The nice thing about this query is that it works even if data is missing. If a student missed a test, they automatically get a zero averaged in.

Conclusion: Queries Are Where It's At

The only reason to put data into a database is to take it out again. The modern database has powerful strategies for ensuring the correctness of data going in (the primary key, foreign key and other constraints) and equally powerful tools for pulling the data back out.

Next Week: Joins Part Two, The Many Forms of JOIN

星期三, 八月 05, 2009

nohup命令详解 zz

http://www.21andy.com/blog/20071121/677.html

使用nohup让程序永远后台运行

Unix/Linux下一般比如想让某个程序在后台运行,很多都是使用 & 在程序结尾来让程序自动运行。比如我们要运行mysql在后台:

/usr/local/mysql/bin/mysqld_safe --user=mysql &

但是加入我们很多程序并不象mysqld一样做成守护进程,可能我们的程序只是普通程序而已,一般这种程序使用 & 结尾,但是如果终端关闭,那么程序也会被关闭。但是为了能够后台运行,那么我们就可以使用nohup这个命令,比如我们有个test.php需要在后台运行,并且希望在后台能够定期运行,那么就使用nohup:

nohup /root/test.php &

  提示:

  [~]$ appending output to nohup.out

  嗯,证明运行成功,同时把程序运行的输出信息放到当前目录的 nohup.out 文件中去。

  附:nohup命令参考

  nohup 命令

  用途:不挂断地运行命令。

  语法:nohup Command [ Arg ... ] [ & ]

   描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。

   无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。

  退出状态:该命令返回下列出口值:

  126 可以查找但不能调用 Command 参数指定的命令。

  127 nohup 命令发生错误或不能查找由 Command 参数指定的命令。

  否则,nohup 命令的退出状态是 Command 参数指定命令的退出状态。

nohup命令及其输出文件

  nohup命令:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。nohup就是不挂起的意思( n ohang up)。

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

使用nohup命令提交作业

如果使用nohup命令提交作业,那么在缺省情况下该作业的所有输出都被重定向到一个名为nohup.out的文件中,除非另外指定了输出文件:

nohup command > myout.file 2>&1 &

在上面的例子中,输出被重定向到myout.file文件中。

使用 jobs 查看任务。

使用 fg %n 关闭。

另外有两个常用的ftp工具ncftpget和ncftpput,可以实现后台的ftp上传和下载,这样我就可以利用这些命令在后台上传和下载文件了。


星期四, 七月 16, 2009

sqlldr 关键词详解

节录重要部分 详情请见:
http://camden-www.rutgers.edu/help/Documentation/Oracle/server.815/a67792/ch06.htm
sqlldr ... Valid Keywords:
userid -- Oracle username/password control -- Control file name log -- Log file name bad -- Bad file name data -- Data file name discard -- Discard file name discardmax -- Number of discards to allow (Default all) skip -- Number of logical records to skip (Default 0) load -- Number of logical records to load (Default all) errors -- Number of errors to allow (Default 50) rows -- Number of rows in conventional path bind array or between direct path data saves (Default: Conventional Path 64, Direct path all) bindsize -- Size of conventional path bind array in bytes (System-dependent default) silent -- Suppress messages during run (header, feedback, errors, discards, partitions, all) direct -- Use direct path (Default FALSE) parfile -- Parameter file: name of file that contains parameter specifications parallel -- Perform parallel load (Default FALSE) readsize -- Size (in bytes) of the read buffer file -- File to allocate extents from

Using Command-Line Keywords

Keywords are optionally separated by commas. They are entered in any order. Keywords are followed by valid arguments.

For example:

SQLLDR CONTROL=foo.ctl, LOG=bar.log, BAD=baz.bad, DATA=etc.dat     USERID=scott/tiger, ERRORS=999, LOAD=2000, DISCARD=toss.dis,    DISCARDMAX=5

星期三, 七月 15, 2009

zz msn無法登入,惱人的810030d 以及81000306 解決方法

http://blog.xuite.net/jackcloud/flyingv/23048209

使用版本msn 9.0,作業環境是XP sp3。安裝好msn9.0後某天突然就無法登入.. 顯示錯誤碼是810030d,不論試了多少次或是重新安裝,都無法順利登入,後來只好先移除掉換回msn 8.5 (方法之一),同時也在尋找解決方式,後來在網路上找到一些方法,順利解決掉8100030d的問題!
解決方式有數種,我每種都有做..orz,分述如下:
用記事本打開 C:\WINDOWS\system32\drivers\etc\hosts 檔案,在最下方加入下列2行:65.54.239.80 messenger.hotmail.com65.54.239.80 dp.msnmessenger.akadns.net存檔後退出記事本。

關掉MSN把C:\Documents and Settings\Your Windows logon name\Local Settings\ApplicationData\Microsoft\Windows Live Contacts\{cc一堆亂碼的資料夾}\DBStore\LogFiles裡的edb這個文件砍掉,然後開MSN就好了。(edb後面有數字的不要砍,否則自己跟朋友之前的顯示名稱都會不見)然後回我的電腦->工具->資料夾選項->檢視-> 改回原來的設定
一般正常狀況8100030d至此會順利排除掉,不過我卻又接著發生了81000306的情況= =,剛好兩個最主要無法登入的錯誤代碼都讓我給遇上了...無言,也是又找了一些解決方法,目前試過有效的就是清除DNS chache,遇到此問題的朋友不妨試試看。
在windows視窗選擇 開始→執行,在執行視窗中輸入cmd 之後再按下Enter鍵。接著在視窗中輸入ipconfig/flushdns 指令再按下〔Enter〕(此指令為清除DNS快取)。

星期二, 六月 30, 2009

Informatica在Import时不能创建shortcut的解决

遇到过Import Source和Target的Instance到Shared Folder以后,不能在Project Folder创建Short Cut的情况。怎么拖,不管Open哪个Folder,都提示是否Copy。
解决:
1. Save Shared Folder
2. Disconnect Project Folder 然后再Connect

其实就是Shared Folder在Import以后没有保存,所以Project不认识。

Comparing Repository Objects -- from Informatica HELP

Comparing Repository Objects


The Repository Manager allows you to compare two repository objects of the same type to identify differences between the objects. For example, you can compare two sessions to check for differences. When you compare two objects, the Repository Manager displays their attributes.

You can compare objects across folders and repositories. To do this, you must have both the folders open. You can compare a reusable object with a non-reusable object. You can also compare different versions of the same object. For more information about versioned objects, see Comparing Versions.

To compare objects, you must have read permission on each folder that contains the objects you want to compare.

You can compare the following types of objects:

  • Designer objects. You can compare Designer objects, such as sources, targets, transformations, mapplets and mappings. For more information about comparing objects in the Designer, see the Designer Guide.
  • Workflow Manager objects. You can compare Workflow Manager objects, such as tasks, sessions, worklets, and workflows. You can compare schedulers and session configuration objects in the Repository Manager, but not in the Workflow Manager. For more information about comparing objects in the Workflow Manager, see the Workflow Administration Guide.

You can compare instances of the same type in detail. For example, if the workflows you compare contain worklet instances with the same name, you can compare the instances to see if they differ. You can compare instances of sessions and tasks in a workflow or worklet comparison. You can compare instances of mappings and transformations in a session comparison. Further, you can compare instances of the same type within a mapping or mapplet comparison.

You cannot compare objects of different types. For example, you cannot compare a source definition with a target definition.

Use the following procedure to compare objects.

To compare repository objects:

  1. In the Repository Manager, connect to the repository.
  2. In the Navigator, select the object you want to compare.

    Tip: To compare the first two objects in a node, select the node.

星期三, 六月 24, 2009

Informatica - Referral - File 1 to File 6 - Free Download


File 1 : File Name: Informatica Repository Guide.pdf
Description: Informatica Repository Guide.pdf
File Size: 9.47 MB
Download Link: http://uploading.com/files/KSN92EQ3/Informatica Repository Guide.pdf.html

File 2 : File Name: Informatica Transformation Guide.pdf
Description: Informatica Transformation Guide.pdf
File Size: 5.94 MB
Download Link: http://uploading.com/files/MSRMFN1X/Informatica Transformation Guide.pdf.html

File 3 : File Name: Informatica Designer Guide1.pdf
Description: Informatica Designer Guide1.pdf
File Size: 7.06 MB
Download Link: http://uploading.com/files/XDUTPB9J/Informatica Designer Guide1.pdf.html

File 4 : File Name: Informatica PowerCenter 7.1.pdf
Description: Informatica PowerCenter 7.1.pdf
File Size: 3.70 MB
Download Link: http://uploading.com/files/PIB6OY2P/Informatica PowerCenter 7.1.pdf.html

File 5 : File Name: Informatica Performance tuning.ppt
Description: Informatica Performance tuning.ppt
File Size: 253 KB
Download Link: http://uploading.com/files/8LTO5D3D/Informatica Performance tuning.ppt.html

File 6 : File Name: Informatica Installtion Configuration Quick start Guide.pdf
Description: Informatica Installtion Configuration Quick start Guide.pdf
File Size: 143 KB
Download Link: http://uploading.com/files/ECTRJMDI/Informatica Installtion %26 Configuration Quick start Guide.pdf.html

Informatica PowerCenter and PowerConnect Adapters 8.6


Informatica PowerCenter and PowerConnect Adapters 8.6 x86 (32bit): 2 GB
File1,http://download.oracle.com/otn/nt/bi/infa_windows_x86_32bit_860_1of2.zip
File2http://download.oracle.com/otn/nt/bi/infa_windows_x86_32bit_860_2of2.zip

x86 (64bit): 1.4 GB
File1,http://download.oracle.com/otn/nt/bi/infa_windows_x86_64bit_860_1of2.zip
File2http://download.oracle.com/otn/nt/bi/infa_windows_x86_64bit_860_2of2.zip

Itanium (64bit): 1.5 GB
File1,http://download.oracle.com/otn/nt/bi/infa_windows_itanium_64bit_860_1of2.zip
File2http://download.oracle.com/otn/nt/bi/infa_windows_itanium_64bit_860_2of2.zip

The Informatica PowerCenter and PowerConnect Adapters may be used with any data source provided the target(s) are: (i) the Oracle Business Intelligence applications programs (excluding Hyperion Financial Performance Management Applications), (ii) the underlying platforms on which the Oracle Business Intelligence Suite Enterprise Edition Plus program, Oracle Business Intelligence Standard Edition One or associated components run, or (iii) a staging database for any of the foregoing. Informatica PowerCenter and PowerConnect Adapters may also be used where the Oracle Business Intelligence applications (excluding Hyperion Financial Performance Management Applications) programs are the source and non-Oracle Business Intelligence application programs are the target, provided, that users do not use Informatica PowerCenter and PowerConnect Adapters to transform the data.

There is no integration service found for this workflow


Error : There is no integration service found for this workflow
When you are doing " Start workFlow" or "Start task" if you are getting this message

What you need to do is :
Check the integration Service.
How to do :

1) Go to informatica Powercenter Workflow manager
2) Click Serivie
3) Click Assign Integration Service
4) Click on the Folder you want to select
5) Click on the Choose Integration Sevice ( If there is only "None" then you need to go to Informatica PowerCenter Administration Console and then create Integration Service ( Lot of process )
6) Click Assign
7) Disconnect and then Reconnet and then perform Start workFlow" or "Start task" .

Step 1STEP 2

星期二, 五月 26, 2009

sed学习笔记

 命令行参数简介 

 

    sed 

    -e script 指定sed编辑命令 

    -f scriptfile 指定的文件中是sed编辑命令 

    -n 寂静模式,抑制来自sed命令执行过程中的冗余输出信息,比如只 

       显示那些被改变的行。 

 

    不明白?不要紧,把这些肮脏丢到一边,跟我往下走,不过下面的介绍里 

    不包括正则表达式的解释,如果你不明白,可能有点麻烦。 

 

 首先假设我们有这样一个文本文件 sedtest.txt 

 

cat > sedtest.txt 

Sed is a stream editor 

---------------------- 

A stream editor is used to perform basic text transformations on an input stream 

-------------------------------------------------------------------------------- 

While in some ways similar to an editor which permits scripted edits (such as ed 

-------------------------------------------------------------------------------- 

sed works by making only one pass over the input(s), and is consequently more 

----------------------------------------------------------------------------- 

efficient. But it is sed's ability to filter text in a pipeline which particular 

-------------------------------------------------------------------------------- 

 

 输出指定范围的行 p other types of editors. 

 

sed -e "1,4p" -n sedtest.txt 

sed -e "/from/p" -n sedtest.txt 

sed -e "1,/from/p" -n sedtest.txt 

 

 在每一行前面增加一个制表符(^I) 

 

sed "s/^/^I/g" sedtest.txt 

 

注意^I的输入方法是ctrl-v ctrl-i 

 

单个^表示行首 

 

 在每一行后面增加--end 

 

sed "s/$/--end/g" sedtest.txt 

 

单个$表示行尾 

 

 显示指定模式匹配行的行号 [/pattern/]= 

 

sed -e '/is/=' sedtest.txt 

 

Sed is a stream editor 

---------------------- 

A stream editor is used to perform basic text transformations on an input stream 

-------------------------------------------------------------------------------- 

While in some ways similar to an editor which permits scripted edits (such as ed 

-------------------------------------------------------------------------------- 

sed works by making only one pass over the input(s), and is consequently more 

----------------------------------------------------------------------------- 

efficient. But it is sed's ability to filter text in a pipeline which particular 

-------------------------------------------------------------------------------- 

sort学习笔记

sort默认是把整行当作一串字符,以首字符排序

------------------------

不指明的sort是对整行的排序: 

xyb 0$ sort a 

a 9 t 

c 2 f 

d 4 x 

 

Pasted from <http://www.unixresources.net/linux/clf/vrml/archive/00/00/34/71/347190.html>

------------------------

 

 

 

Sort -nk 5

以第5列进行排序

-n表示numberic排序

-k表示位置??

 

-r  reverse 降序排列

 

+1 对第二列排序,如:(字段从0开始数,第一字段是0

-----------------------------------------

按数字顺序排序第二个字段: 

xyb 0$ sort -n +1 a 

c 2 f 

d 4 x 

a 9 t 

 

Pasted from <http://www.unixresources.net/linux/clf/vrml/archive/00/00/34/71/347190.html>

-------------------------------------------

 

 

两个字段排序:

-------------------------------------------

先按第二个、不按第三个字段排序: (这个解释估计错了,应该是第二字段升序,第三字段降序)

xyb 0$ sort +1 -2 a 

c 2 f 

d 4 x 

a 9 t 

d 9 c 

+POS1 [-POS2]属于比较老的用法,现在gnu sort里推荐使用-k POS1[,POS2] 

表示排序关键字从POS1开始,到POS2中止。详细信息参考man sortinfo sort

Pasted from <http://www.unixresources.net/linux/clf/vrml/archive/00/00/34/71/347190.html>

-------------------------------------------

 

 

-t 指定分隔符

-------------------------------------------

xyb 0$ sed 's/ /$/g' a | sort -t$ -n +1 

c$2$f 

d$4$x 

a$9$t 

 

Pasted from <http://www.unixresources.net/linux/clf/vrml/archive/00/00/34/71/347190.html>

-------------------------------------------

HPUX上Oracle 11g client安装笔记

OS:HPUX
hardware:安腾CPU
安装对象:
Oracle 11.1.0.6 client
sqlldr,sqlplus
Oracle 11.1.0.7 patch

sqlldr和sqlplus安装后,文件在$ORACLE_HOME/bin 下面
runtime安装会自动包含sqlplus
sqlldr在custome安装下面的oracle database utilities组件里,有其他东西,据说蛮有用,都装了
admin安装会包含sqlldr

安装界面出来,welcome下面有一步Inventory Directory,是临时安装文件存放的地方。保持这个路径为空或者删掉最后一级路径都可以。每次安装oracle都会重新copy内容进去的。

sqlldr起不起来的原因:
1. /u01/app/oracle/product/11.1.0.6/client_1/bin 这个路径要有rrr权限
2. sqlldr文件要有xxx权限
3. ORACLE_HOME要设进.profile

查看是否安腾处理器方法:
machinfo(Itanium机器可用)或者 ioscan,dmesg,model(非Itanium机器)

用unix连接XWindow以显示图形界面:
1.打开软件ReflectionX或者Xwindow软件,不要任何设置或者连接
2.export DISPLAY=16.100.129.5:0.0(在unix上直接输入这段命令,红色部分填你的电脑IP,这样执行runInstaller的时候unix会去连你电脑上的ReflectionX)
3.在安装文件解压的路径下:
cd client 
./runInstaller -ignoreSysPrereqs
安装7patch的时候
cd Disk1
./runInstaller

星期三, 五月 06, 2009

unix环境变量介绍

我们在Linux下安装系统软件的时候,经常遇到一些系统环境变量配置的问题。什么是环境变量?如何定制环境变量?我将在下面做一些介绍。

一、什么是环境变量?
Linux是一个多用户的操作系统。多用户意味着每个用户登录系统后,都有自己专用的运行环境。而这个环境是由一组变量所定义,这组变量被称为环境变量。用户可以对自己的环境变量进行修改以达到对环境的要求。

二、定制环境变量 
环境变量是和Shell紧密相关的,它是通过Shell命令来设置的。环境变量又可以被所有当前用户所运行的程序所使用。对于bash来说,可以通过变量名来访问相应的环境变量。
下面通过几个实例来说明

1.显示环境变量HOME 
$&nbspecho $HOME
/home/admin

2.设置一个新的环境变量NAME
$&nbspexport&nbspNAME="RaidCheng"
$&nbspecho $NAME
RaidCheng

3.使用env命令显示所有的环境变量 
$&nbspenv
HOSTNAME=test
TERM=vt100
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=202.xxx.xxx.xxx&nbsp53694&nbsp22
CATALINA_BASE=/usr/local/jakarta-tomcat
SSH_TTY=/dev/pts/0
ANT_HOME=/usr/local/ant
JAVA_OPTS=-server
USER=admin
...

4.使用set命令显示所有本地定义的Shell变量 
$&nbspset
BASH=/bin/bash
BASH_VERSINFO=([0]="2" [1]="05b" [2]="0" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu")
BASH_VERSION='2.05b.0(1)-release'
CATALINA_BASE=/usr/local/jakarta-tomcat
CATALINA_HOME=/usr/local/jakarta-tomcat
...

5.使用unset命令来清除环境变量 
$&nbspexport&nbspNAME="RaidCheng"
$&nbspecho $NAME
RaidCheng
$&nbspunset&nbspNAME
$&nbspecho $NAME

6.使用readonly命令设置只读变量 
$&nbspexport&nbspNAME="RaidCheng"
$&nbspreadonly&nbspNAME
$&nbspunset&nbspNAME
-bash:&nbspunset:&nbspNAME:&nbspcannot&nbspunset:&nbspreadonly&nbspvariable
$&nbspNAME="New" #会发现此也变量不能被修改
-bash:&nbspTEST:&nbspreadonly&nbspvariable

三、常见的环境变量 
PATH      决定了shell将到哪些目录中寻找命令或程序
HOME      当前用户主目录
HISTSIZE    历史记录数
LOGNAME     当前用户的登录名 
HOSTNAME    指主机的名称
SHELL      前用户Shell类型 
LANGUGE     语言相关的环境变量,多语言可以修改此环境变量
MAIL      当前用户的邮件存放目录 
PS1       基本提示符,对于root用户是#,对于普通用户是$
PS2       附属提示符,默认是“>”

四、通过C程序来访问和设置环境变量 
对于C程序的用户来说,可以使用下列三个函数来设置或访问一个环境变量。 

getenv()访问一个环境变量。输入参数是需要访问的变量名字,返回值是一个字符串。如果所访问的环境变量不存在,则会返回NULL

setenv()在程序里面设置某个环境变量的函数

unsetenv()清除某个特定的环境变量的函数

另外,还有一个指针变量environ,它指向的是包含所有的环境变量的一个列表。下面的程序可以打印出当前运行环境里面的所有环境变量:

#include 
extern&nbspchar**environ;
int&nbspmain ()
{
char**var;
for (var =environ;*var !=NULL;++var)
printf ("%s \n ",*var);
return 0;
}

五、环境变量文件
通过修改一些相关的环境定义文件来修改环境变量,比如对于RedHat,与环境相关的文件有/etc/profile和~/.bash_profile等。修改完毕后重新登录一次或运行命令source&nbspxxx就生效了。

星期二, 四月 14, 2009

http://51ajax.net/?p=49

转载自:http://51ajax.net/?p=49

如果html中字体大小是用像素px来定义,那么在IE中无法调整字体大小。

chm同IE一样,所以对于不得不长时间坐在屏幕前的我们是件很痛苦的事。

前阵偶尔看见IE可以让用户嵌入自己的CSS样式表,就是使用

工具 - Internet选项 - 常规 - 辅助功能 - 用户样式表

来定义。把自己的CSS写好,比如 * {font-size:20px;} ,然后嵌入。

在chm里设置和IE设置一样,只设置一个即可,

选项 - Internet选项 - ……

################################

工具 - Internet选项 - 常规 - 辅助功能 - 格式

  •  不使用网页指定的颜色
  • 不使用网页指定的字体样式
  • 不使用网页指定的字体大小

以上三项勾选后,IE的背景可以变为系统背景色,我们可以设置为浅绿色,浅黄色等

字体大小就可以使用Ctrl+滚轮调节了(即使用像素定义的也可以)

################################

OK,大功告成,保护眼睛每一天。

星期三, 四月 08, 2009

AWK:Linux 管理员的智能工具包 zz

http://www.oracle.com/technology/global/cn/pub/articles/dulaney_awk.html

AWKLinux 管理员的智能工具包
作者 Emmett Dulaney

您正在学习 Linux 吗?本文对于非常有用的 AWK 文本操作工具进行了介绍,非常有价值。

AWK 实用工具带有其自己的自包含语言,它不仅是 Linux 中也是任何环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人 Alfred AhoPeter Weinberger Brian Kernighan 姓氏的首个字母)的最大功能取决于一个人所拥有的知识。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

AWK 是什么?

最简单地说,AWK 是一种用于处理文本的编程语言工具。AWK 实用工具的语言在很多方面类似于 shell 编程语言,尽管 AWK 具有完全属于其本身的语法。在最初创造 AWK 时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。

尽管操作可能会很复杂,但命令的语法始终是:

awk '{pattern + action}' {filenames}

其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号 ({}) 不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。

了解字段

实用工具将每个输入行分为记录和字段。记录是单行的输入,而每条记录包含若干字段。默认的字段分隔符是空格或制表符,而记录的分隔符是换行。虽然在默认情况下将制表符和空格都看作字段分隔符(多个空格仍然作为一个分隔符),但是可以将分隔符从空格改为任何其它字符。

为了进行演示,请查看以下保存为 emp_names 的员工列表文件:

46012   DULANEY     EVAN        MOBILE   AL

46013   DURHAM      JEFF        MOBILE   AL

46015   STEEN       BILL        MOBILE   AL

46017   FELDMAN     EVAN        MOBILE   AL

46018   SWIM        STEVE       UNKNOWN  AL

46019   BOGUE       ROBERT      PHOENIX  AZ

46021   JUNE        MICAH       PHOENIX  AZ

46022   KANE        SHERYL      UNKNOWN  AR

46024   WOOD        WILLIAM     MUNCIE   IN

46026   FERGUS      SARAH       MUNCIE   IN

46027   BUCK        SARAH       MUNCIE   IN

46029   TUTTLE      BOB         MUNCIE   IN

AWK 读取输入内容时,整条记录被分配给变量 $0。每个字段以字段分隔符分开,被分配给变量 $1$2$3 等等。一行在本质上可以包含无数个字段,通过字段号来访问每个字段。因此,命令

awk '{print $1,$2,$3,$4,$5}' names

将会产生的打印输出是

46012 DULANEY EVAN MOBILE AL

46013 DURHAM JEFF MOBILE AL

46015 STEEN BILL MOBILE AL

46017 FELDMAN EVAN MOBILE AL

46018 SWIM STEVE UNKNOWN AL

46019 BOGUE ROBERT PHOENIX AZ

46021 JUNE MICAH PHOENIX AZ

46022 KANE SHERYL UNKNOWN AR

46024 WOOD WILLIAM MUNCIE IN

46026 FERGUS SARAH MUNCIE IN

46027 BUCK SARAH MUNCIE IN

46029 TUTTLE BOB MUNCIE IN

值得注意的一项重要内容是,AWK 解释由空格分隔的五个字段,但当它打印显示内容时,在每个字段间只有一个空格。利用为每个字段指定了唯一号码的功能,您可以选择只打印特定的字段。例如,只打印每条记录的姓名时,只需选择第二个和第三个字段进行打印:

$ awk '{print $2,$3}' emp_names

DULANEY EVAN

DURHAM JEFF

STEEN BILL

FELDMAN EVAN

SWIM STEVE

BOGUE ROBERT

JUNE MICAH

KANE SHERYL

WOOD WILLIAM

FERGUS SARAH

BUCK SARAH

TUTTLE BOB

$

您还可以指定按任何顺序打印字段,而无论它们在记录中是如何存在的。因此,只需要显示姓名字段,并且使其顺序颠倒,先显示名字再显示姓氏:

$ awk '{print $3,$2}' emp_names

EVAN DULANEY

JEFF DURHAM

BILL STEEN

EVAN FELDMAN

STEVE SWIM

ROBERT BOGUE

MICAH JUNE

SHERYL KANE

WILLIAM WOOD

SARAH FERGUS

SARAH BUCK

BOB TUTTLE

$

使用模式

通过包含一个必须匹配的模式,您可以选择只对特定的记录而不是所有的记录进行操作。模式匹配的最简单形式是搜索,其中要匹配的项目被包含在斜线 (/pattern/) 中。例如,只对那些居住在阿拉巴马州的员工执行前面的操作:

$ awk '/AL/ {print $3,$2}' emp_names

EVAN DULANEY

JEFF DURHAM

BILL STEEN

EVAN FELDMAN

STEVE SWIM

$

如果您不指定要打印的字段,则会打印整个匹配的条目:

$ awk '/AL/' emp_names

46012   DULANEY     EVAN     MOBILE     AL

46013   DURHAM      JEFF     MOBILE     AL

46015   STEEN       BILL     MOBILE     AL

46017   FELDMAN     EVAN     MOBILE     AL

46018   SWIM        STEVE    UNKNOWN    AL

$

对同一数据集的多个命令可以用分号 (;) 分隔开。例如,在一行中打印姓名,而在另一行中打印城市和州名:

$ awk '/AL/ {print $3,$2 ; print $4,$5}' emp_names

EVAN DULANEY

MOBILE AL

JEFF DURHAM

MOBILE AL

BILL STEEN

MOBILE AL

EVAN FELDMAN

MOBILE AL

STEVE SWIM

UNKNOWN AL

$

如果没有使用分号 (print $3,$2,$4,$5),则会在同一行中显示所有内容。另一方面,如果分别给出两个打印语句,则会产生完全不同的结果:

$ awk '/AL/ {print $3,$2} {print $4,$5}' emp_names

EVAN DULANEY

MOBILE AL

JEFF DURHAM

MOBILE AL

BILL STEEN

MOBILE AL

EVAN FELDMAN

MOBILE AL

STEVE SWIM

UNKNOWN AL

PHOENIX AZ

PHOENIX AZ

UNKNOWN AR

MUNCIE IN

MUNCIE IN

MUNCIE IN

MUNCIE IN

$

只有在列表中找到 AL 时才会给出字段三和字段二。但是,字段四和字段五是无条件的,始终打印它们。只有第一组花括号中的命令对前面紧邻的命令 (/AL/) 起作用。

结果非常不便于阅读,可以使其稍微更清晰一些。首先,在城市与州之间插入一个空格和逗号。然后,在每两行显示之后放置一个空行:

$ awk '/AL/ {print $3,$2 ; print $4", "$5"\n"}' emp_names

EVAN DULANEY

MOBILE, AL

 

JEFF DURHAM

MOBILE, AL

 

BILL STEEN

MOBILE, AL

 

EVAN FELDMAN

MOBILE, AL

 

STEVE SWIM

UNKNOWN, AL

$

在第四和第五个字段之间,添加一个逗号和一个空格(在引号之间),在第五个字段后面,打印一个换行符 (\n)。在 AWK 打印语句中还可以使用那些可在 echo 命令中使用的所有特殊字符,包括:

  • \n(换行)
  • \t(制表)
  • \b(退格)
  • \f(进纸)
  • \r(回车)

因此,要读取全部五个最初由制表符分隔开的字段,并且也利用制表符打印它们,您可以编程如下

$ awk '{print $1"\t"$2"\t"$3"\t"$4"\t"$5}' emp_names

46012   DULANEY     EVAN     MOBILE    AL

46013   DURHAM      JEFF     MOBILE    AL

46015   STEEN       BILL     MOBILE    AL

46017   FELDMAN     EVAN     MOBILE    AL

46018   SWIM        STEVE    UNKNOWN   AL

46019   BOGUE       ROBERT   PHOENIX   AZ

46021   JUNE        MICAH    PHOENIX   AZ

46022   KANE        SHERYL   UNKNOWN   AR

46024   WOOD        WILLIAM  MUNCIE    IN

46026   FERGUS      SARAH    MUNCIE    IN

46027   BUCK        SARAH    MUNCIE    IN

46029   TUTTLE      BOB      MUNCIE    IN

$

通过连续设置多项标准并用管道 (|) 符号将其分隔开,您可以一次搜索多个模式匹配:

$ awk '/AL|IN/' emp_names

46012   DULANEY     EVAN     MOBILE    AL

46013   DURHAM      JEFF     MOBILE    AL

46015   STEEN       BILL     MOBILE    AL

46017   FELDMAN     EVAN     MOBILE    AL

46018   SWIM        STEVE    UNKNOWN   AL

46024   WOOD        WILLIAM  MUNCIE    IN

46026   FERGUS      SARAH    MUNCIE    IN

46027   BUCK        SARAH    MUNCIE    IN

46029   TUTTLE      BOB      MUNCIE    IN

$

这样可找到每个阿拉巴马州和印第安那州居民的匹配记录。但是在试图找出居住在亚利桑那州的人时,出现了一个问题:

$ awk '/AR/' emp_names

46019   BOGUE       ROBERT   PHOENIX   AZ

46021   JUNE        MICAH    PHOENIX   AZ

46022   KANE        SHERYL   UNKNOWN   AZ

46026   FERGUS      SARAH    MUNCIE    IN

46027   BUCK        SARAH    MUNCIE    IN

$

员工 46026 46027 没有住在亚利桑那州;但是他们的名字中包含所搜索的字符序列。切记,当在 AWK 中进行模式匹配时,例如 grepsed 或者大部分其他 Linux/Unix 命令,将在记录(行)中的任何位置查找匹配,除非指定进行其他操作。为解决这一问题,必须将搜索与特定字段联系起来。通过利用代字号 (˜) 以及对特定字段的说明,可以达到这一目的,如下例所示:

$ awk '$5 ˜ /AR/' emp_names

46019   BOGUE       ROBERT   PHOENIX   AZ

46021   JUNE        MICAH    PHOENIX   AZ

46022   KANE        SHERYL   UNKNOWN   AZ

$

代字号(表示匹配)的对应符号是一个前面带有感叹号的代字号 (!˜)。这些字符通知程序,如果搜索序列没有出现在指定字段中,则找出与搜索序列相匹配的所有行:

$ awk '$5 !˜ /AR/' names

46012   DULANEY     EVAN     MOBILE    AL

46013   DURHAM      JEFF     MOBILE    AL

46015   STEEN       BILL     MOBILE    AL

46017   FELDMAN     EVAN     MOBILE    AL

46018   SWIM        STEVE    UNKNOWN   AL

46024   WOOD        WILLIAM  MUNCIE    IN

46026   FERGUS      SARAH    MUNCIE    IN

46027   BUCK        SARAH    MUNCIE    IN

46029   TUTTLE      BOB      MUNCIE    IN

$

在这种情况下,将显示第五个字段中没有 AR 的所有行包括两个 Sarah 条目,这两个条目确实包含 AR,但却是在第三个字段而不是第五个字段中。

花括号和字段分隔符

括号字符在 AWK 命令中起着很重要的作用。出现在括号之间的操作指出将要发生什么以及何时发生。当只使用一对括号时:

{print $3,$2}

括号间的所有操作同时发生。当使用多于一对的括号时:

{print $3}{print $2}

执行第一组命令,在该命令完成后执行第二组命令。注意以下两列清单的区别:

$ awk '{print $3,$2}' names

EVAN DULANEY

JEFF DURHAM

BILL STEEN

EVAN FELDMAN

STEVE SWIM

ROBERT BOGUE

MICAH JUNE

SHERYL KANE

WILLIAM WOOD

SARAH FERGUS

SARAH BUCK

BOB TUTTLE

$

 

$ awk '{print $3}{print $2}' names

EVAN

DULANEY

JEFF

DURHAM

BILL

STEEN

EVAN

FELDMAN

STEVE

SWIM

ROBERT

BOGUE

MICAH

JUNE

SHERYL

KANE

WILLIAM

WOOD

SARAH

FERGUS

SARAH

BUCK

BOB

TUTTLE

$

要利用多组括号进行重复查找,执行第一组中的命令直到完成为止;然后处理第二组命令。如果有第三组命令,则在第二组命令完成后执行它,以此类推。在所生成的打印输出中,有两个分隔的打印命令,因此先执行第一个命令,随后执行第二个命令,这样导致每个条目显示在两行而不是一行中。

区分两个字段的字段分隔符不一定始终是空格;它可以是任何可识别的字符。为进行演示,假定 emp_names 文件利用冒号而不是制表符来分隔字段:

$ cat emp_names

46012:DULANEY:EVAN:MOBILE:AL

46013:DURHAM:JEFF:MOBILE:AL

46015:STEEN:BILL:MOBILE:AL

46017:FELDMAN:EVAN:MOBILE:AL

46018:SWIM:STEVE:UNKNOWN:AL

46019:BOGUE:ROBERT:PHOENIX:AZ

46021:JUNE:MICAH:PHOENIX:AZ

46022:KANE:SHERYL:UNKNOWN:AR

46024:WOOD:WILLIAM:MUNCIE:IN

46026:FERGUS:SARAH:MUNCIE:IN

46027:BUCK:SARAH:MUNCIE:IN

46029:TUTTLE:BOB:MUNCIE:IN

$

如果试图通过指定所需要的第二个字段来打印姓氏

$ awk '{print $2}' emp_names

您最后会得到十二个空行。因为文件中没有空格,除了第一个字段之外没有可认别的字段。为解决这一问题,必须通知 AWK 是空格之外的另一个字符作为分隔符,有两种方法可通知 AWK 使用新的字段分隔符:使用命令行参数 -F,或在程序中指定变量 FS。两种方法的效果相同,只有一种例外情况,如下例所示:

$ awk '{FS=":"}{print $2}' emp_names

 

DURHAM

STEEN

FELDMAN

SWIM

BOGUE

JUNE

KANE

WOOD

FERGUS

BUCK

TUTTLE

$

 

$ awk -F: '{print $2}' emp_names

DULANEY

DURHAM

STEEN

FELDMAN

SWIM

BOGUE

JUNE

KANE

WOOD

FERGUS

BUCK

TUTTLE

$

在第一个命令中,头一条记录返回不正确的空行,而其他结果正确。直到读取第二条记录时,才识别字段分隔符并正确地执行。通过使用 BEGIN 语句可以纠正这一缺点(在后文详述)。-F 的功能非常类似于 BEGIN,能够正确地读取第一条记录并按要求执行。

在本文开始处我曾提到,默认的显示/输出字段分隔符是空格。通过使用输出字段分隔符 (OFS) 变量,可以在程序中更改此特性。例如,要读取文件(由冒号分隔)并以短划线显示,则命令是

$ awk -F":" '{OFS="-"}{print $1,$2,$3,$4,$5}' emp_names

46012-DULANEY-EVAN-MOBILE-AL

46013-DURHAM-JEFF-MOBILE-AL

46015-STEEN-BILL-MOBILE-AL

46017-FELDMAN-EVAN-MOBILE-AL

46018-SWIM-STEVE-UNKNOWN-AL

46019-BOGUE-ROBERT-PHOENIX-AZ

46021-JUNE-MICAH-PHOENIX-AZ

46022-KANE-SHERYL-UNKNOWN-AR

46024-WOOD-WILLIAM-MUNCIE-IN

46026-FERGUS-SARAH-MUNCIE-IN

46027-BUCK-SARAH-MUNCIE-IN

46029-TUTTLE-BOB-MUNCIE-IN

$

FS  OFS 是(输入)字段分隔符和输出字段分隔符,它们只是一对可以在 AWK 实用工具中使用的变量。例如,要在打印时为每行编号,可以采用以下方式使用 NR 变量:

$ awk -F":" '{print NR,$1,$2,$3}' emp_names

1 46012 DULANEY EVAN

2 46013 DURHAM JEFF

3 46015 STEEN BILL

4 46017 FELDMAN EVAN

5 46018 SWIM STEVE

6 46019 BOGUE ROBERT

7 46021 JUNE MICAH

8 46022 KANE SHERYL

9 46024 WOOD WILLIAM

10 46026 FERGUS SARAH

11 46027 BUCK SARAH

12 46029 TUTTLE BOB

$

找出员工号码处于 46012 46015 之间的所有行:

$ awk -F":" '/4601[2-5]/' emp_names

46012   DULANEY EVAN  MOBILE AL

46013   DURHAM  JEFF  MOBILE AL

46015   STEEN   BILL  MOBILE AL

$

添加文本

可以按照添加控制序列或其他字符的相同方式将文本添加到显示中。例如,要将分隔符从空格改为冒号,则命令是

awk '{print $1":"$2":"$3":"$4":"$5}' emp_names > new_emp_names

在这种情况下,字符 (:) 包含在引号 ("/") 中,它被添加到每个字段之间。在引号之间的值可以是任何内容。例如,创建一个关于居住在阿拉巴马州的员工的外观类似数据库的显示:

$ awk '$5 ~ /AL/ {print "NAME: "$2", "$3"\nCITY-STATE:

  "$4", "$5"\n"}' emp_names

 

NAME: DULANEY, EVAN

CITY-STATE: MOBILE, AL

 

NAME: DURHAM, JEFF

CITY-STATE: MOBILE, AL

 

NAME: STEEN, BILL

CITY-STATE: MOBILE, AL

 

NAME: FELDMAN, EVAN

CITY-STATE: MOBILE, AL

 

NAME: SWIM, STEVE

CITY-STATE: UNKNOWN, AL

$

数学操作

AWK 除了提供文本功能,还提供全部范围的算术操作符,包括以下符号:

将数字相加



执行指数运算
提供模
++ 
将变量值加一
+= 
将其他操作的结果分配给变量
— 
将变量减一
-= 
将减法操作的结果分配给变量
*= 
分配乘法操作的结果
/= 
分配除法操作的结果
%= 
分配求模操作的结果

例如,假定您的机器上存在以下的文件,详细地列出硬件商店中的物品:

$ cat inventory

hammers 5       7.99

drills  2      29.99

punches 7       3.59

drifts  2       4.09

bits   55       1.19

saws  123      14.99

nails 800        .19

screws 80        .29

brads 100        .24

$

第一项业务定单是通过将第二个字段(数量)的值乘以第三个字段(价格)的值,计算每种物品的库存价值:

$ awk '{print $1,"QTY: "$2,"PRICE: "$3,"TOTAL: "$2*$3}' inventory

hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95

drills QTY: 2 PRICE: 29.99 TOTAL: 59.98

punches QTY: 7 PRICE: 3.59 TOTAL: 25.13

drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18

bits QTY: 55 PRICE: 1.19 TOTAL: 65.45

saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77

nails QTY: 800 PRICE: .19 TOTAL: 152

screws QTY: 80 PRICE: .29 TOTAL: 23.2

brads QTY: 100 PRICE: .24 TOTAL: 24

$

如果这些行本身并不重要,您只是希望确定商店中有多少件物品,则可以分配一个普通变量,按照每条记录中的物品数量增加:

$ awk '{x=x+$2} {print x}' inventory

5

7

14

16

71

194

994

1074

1174

$

根据这一数据,商店中有 1174 件物品。第一次执行时,变量 x 没有值,因此它采用第一行第二个字段的值。第二次执行时,它保留了第一行的值并加上第二行的值,以此类推,直到达到累计的总合。

可以应用相同的过程来确定现有库存的总价值:

$ awk '{x=x+($2*$3)} {print x}' inventory

39.95

99.93

125.06

133.24

198.69

2042.46

2194.46

2217.66

2241.66

$

因此,1174 件物品的价值是 $2,241.66。虽然这一过程可以获得总计值,但它的外观很差,需要加工成实际的报表。利用一些附加项,很容易使显示变得更整洁:

$ awk '{x=x+($2*$3)}{print $1,"QTY: "$2,"PRICE: "$3,"TOTAL: "$2*$3,"BAL: "x}' inventory

hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95 BAL: 39.95

drills QTY: 2 PRICE: 29.99 TOTAL: 59.98 BAL: 99.93

punches QTY: 7 PRICE: 3.59 TOTAL: 25.13 BAL: 125.06

drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18 BAL: 133.24

bits QTY: 55 PRICE: 1.19 TOTAL: 65.45 BAL: 198.69

saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77 BAL: 2042.46

nails QTY: 800 PRICE: .19 TOTAL: 152 BAL: 2194.46

screws QTY: 80 PRICE: .29 TOTAL: 23.2 BAL: 2217.66

brads QTY: 100 PRICE: .24 TOTAL: 24 BAL: 2241.66

$

该过程提供了每条记录的清单,同时将总价值分配给库存值,并保持商店资产的运作平衡。

BEGIN  END

使用 BEGIN  END 语句可以分别指定在处理实际开始之前或者完成之后进行操作。BEGIN 语句最常用于建立变量或显示标题。另一方面,END 语句可用于在程序结束后继续进行处理。

在前面的示例中,利用以下例程生成了物品的总价值:

awk '{x=x+($2*$3)} {print x}' inventory

该例程在运行总计累加时显示了文件中的每一行。没有其他方法可以指定它,而不让在每一行进行打印也导致它始终不打印出来。但是,利用 END 语句可以避免这一问题:

$ awk '{x=x+($2*$3)} END {print "Total Value of Inventory:"x}' inventory

Total Value of Inventory: 2241.66

$

定义了变量 x,它对每一行进行处理;但是,在所有处理完成之前不会生成显示。尽管可以作为独立例程使用,它也可以置入到先前的代码列表,添加更多信息并生成更完整的报表:

$ awk '{x=x+($2*$3)} {print $1,"QTY: "$2,"PRICE:

    "$3,"TOTAL: "$2*$3} END {print "Total Value of Inventory: " x}' inventory

 

hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95

drills QTY: 2 PRICE: 29.99 TOTAL: 59.98

punches QTY: 7 PRICE: 3.59 TOTAL: 25.13

drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18

bits QTY: 55 PRICE: 1.19 TOTAL: 65.45

saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77

nails QTY: 800 PRICE: .19 TOTAL: 152

screws QTY: 80 PRICE: .29 TOTAL: 23.2

brads QTY: 100 PRICE: .24 TOTAL: 24

Total Value of Inventory: 2241.66

$

BEGIN 命令与 END 的工作方式相同,但它建立了那些需要在完成其他工作之前所做的项目。该过程最常见的目的是创建报表的标题。此例程的语法类似于

$ awk 'BEGIN {print "ITEM   QUANTITY   PRICE   TOTAL"}'

输入、输出和源文件

AWK 工具可以从文件中读取其输入,正如在此之前所有示例所做的那样,它也可以从其他命令的输出中获取输入。例如:

$ sort emp_names | awk '{print $3,$2}'

awk 命令的输入是排序操作的输出。除了 sort,还可以使用任何其他的 Linux 命令例如 grep。该过程允许您在离开所选定字段前对文件执行其他操作。

类似于解释程序,AWK 使用输出改向操作符 >  >> 将其输出放入文件中而不是标准输出设备。这些符号的作用类似于它们在解释程序中的对应符号,因此 > 在不存在文件时创建文件,而 >> 追加到现有文件的尾部。请看以下的示例:

$ awk '{print NR, $1 ) > "/tmp/filez" }' emp_names

$ cat /tmp/filez

1       46012

2       46013

3       46015

4       46017

5       46018

6       46019

7       46021

8       46022

9       46024

10      46026

11      46027

12      46029

$

检查该语句的语法,您会看到输出改向是在打印语句完成后进行的。必须将文件名包含在引号中,否则它只是一个未初始化的 AWK 变量,而将指令联接起来会在 AWK 中产生错误。(如果不正确地使用改向符号,则 AWK 无法了解该符号意味着改向还是一个关系操作符。)

AWK 中输出到管道也类似于解释程序中所实现的相同操作。要将打印命令的输出发送到管道中,可以在打印命令后附加管道符号以及命令的名称,如下所示:

$ awk '{ print $2 | "sort" }' emp_names

BOGUE

BUCK

DULANEY

DURHAM

FELDMAN

FERGUS

JUNE

KANE

STEEN

SWIM

TUTTLE

WOOD

$

这是输出改向的情况,必须将命令包含在引号中,而管道的名称是被执行命令的名称。

AWK 所使用的命令可以来自两个地方。首先,可以在命令行中指定它们,如示例中所示。其次,它们可以由源文件提供。如果是这种情况,通过 -f 选项将这种情况向 AWK 发出警告。演示如下:

$ cat awklist

{print $3,$2}

{print $4,$5,"\n"}

$

 

$ awk -f awklist emp_names

EVAN DULANEY

MOBILE AL

 

JEFF DURHAM

MOBILE AL

 

BILL STEEN

MOBILE AL

 

EVAN FELDMAN

MOBILE AL

 

STEVE SWIM

UNKNOWN AL

 

ROBERT BOGUE

PHOENIX AZ

 

MICAH JUNE

PHOENIX AZ

 

SHERYL KANE

UNKNOWN AR

 

WILLIAM WOOD

MUNCIE IN

 

SARAH FERGUS

MUNCIE IN

 

SARAH BUCK

MUNCIE IN

 

BOB TUTTLE

MUNCIE IN

 

$

注意,在源文件中的任何地方或者在命令行中调用它时,不使用单引号。单引号只用于区别命令行中的命令与文件名称。

如果简单的输出不能处理您的程序中所需要的复杂信息,则可以尝试由 printf 命令获得的更加复杂的输出,其语法是

printf( format, value, value ...)

该语法类似于 C 语言中的 printf 命令,而格式的规格是相同的。通过插入一项定义如何打印数值的规格,可以定义该格式。格式规格包含一个跟有字母的 %。类似于打印命令,printf 不必包含在圆括号中,但是可以认为使用圆括号是一种良好的习惯。

下表列出 printf 命令提供的各种规格。

规格

说明

%c

打印单个 ASCII 字符

%d

打印十进制数

%e

打印数字的科学计数表示

%f

打印浮点表示

%g

打印 %e %f;两种方式都更简短

%o

打印无符号的八进制数

s

打印 ASCII 字符串

%x

打印无符号的十六进制数

%%

打印百分号;不执行转换

可以在 % 与字符之间提供某些附加的格式化参数。这些参数进一步改进数值的打印方式:

参数

说明

-

将字段中的表达式向左对齐

,width

根据需要将字段补齐到指定宽度(前导零使用零将字段补齐)

.prec

小数点右面数字的最大字符串宽度或最大数量

printf 命令能够控制并将数值从一种格式转换为另一种格式。当需要打印变量的值时,只需提供一种规格,指示 printf 如何打印信息(通常包含在双引号中)即可。必须为每个传递到 printf 的变量包含一个规格参数;如果包含过少的参数,则 printf 不会打印所有的数值。

处理错误

AWK 工具报告所发生错误的方式很令人恼火。一个错误会阻碍任何操作的进行,所提供的错误信息非常含混不清:

awk: syntax error near line 2

awk: bailing out near line 2

您可能会花几小时的时间查看第 2 行,试图找出它为什么阻碍程序运行;这就是支持使用源文件的一个有力论据。

切记有两条规则可以帮助您避免出现语法错误:

1. 确保命令位于括号中,而括号位于单引号中。没有使用这些字符之一必然导致程序无法运行。

2. 搜索命令需要位于斜线之间。要找出住在印第安那州的员工,您必须使用/IN/而不是IN

结论

尽管 AWK 完全代表另外的含意,但它应该是管理员智能工具包的首字母缩写。连同 SED 一起,AWK 实用工具是 Linux 管理员所拥有的功能最强大和灵活的工具之一。通过了解其语言的一些特性,您可以开辟出能够简化任务的领域,否则这些任务将会是非常费时和困难的。