awk知识

来源:互联网 发布:mac linux 命令区别 编辑:程序博客网 时间:2024/06/04 23:24
<sed & awk> 第七章部分笔记  希望对大家有所帮助转自 bbs.chinaunix.net/thread-692472-1-1.html
编写awk脚本
====================
1. 从 Hello, World 开始
====================
we create a file named test that contains a single line. This example shows a script that contains the print statement:
  1. $ echo 'this line of data is ignored' > test
  2. $ awk '{ print "hello, world"}' test
复制代码

This scripts has only a single action, which is enclosed in braces.
这个脚本只有一个动作,  被放在{}中. 这个动作是为每行的输出执行print语句.
在这里test文件只有一行, 所以 这个动作只执行一次
注意, 读入的test文件里的行是不会输出的

Now let's look at another example. Here , we use a file that contains the line "Hello, World. "
  1. $cat test2
  2. Hello, world
  3. $awk '{print}' test2
  4. Hello, world
复制代码

这里输出是Hello world ,
执行不带参数的print语句 , print就只是把读入的行简单的输出, 如果test2中有多行, 同样的awk读入几行就输出几行Hello world

上面的例子说明awk的运行是依赖它读取的内容, 也就是说当awk的输入为空的时候 它什么都不会做 (BEGIN部分除外)
比如
  1. $ > test
  2. $ awk '{print "hello world"}' test
  3. $
复制代码



当你运行一个awk程序 , 它从你提供的文件来读取, 检查awk指令语法, 然后awk 尝试把文件的每一行作为输入 来执行指令 , 所以只有当awk冲文件中读取到内容才执行动作

我们可以自己检验 输入第一个例子  但是 不输入文件名
你会发现awk 希望从键盘得到输入 它才会执行print指令:
敲几下回车  然后输入"EOF"(一般是CTRL-D) ,  每当你输入一次回车
都会执行print "hello, world"这个动作

除了上面两中hello world方法外, 还有另一种hello world 可以让awk不需要输入就执行动作的方法.    这个方法就是在动作的前面使用BEGIN参数.

begin 参数指定 在读到输入的第一行之前执行动作
  1. $ awk 'BEGIN {print "Hello, world"}'
  2. Hello, world
复制代码


当awk程序只有一个BEGIN部分,而没有其他语句,awk将不处理任何输入

$ awk 'BEGIN{}' xxxx
# 正常执行 不关xxxx文件存不存在  因为语法正确 只有一个BEGIN部分 awk执行BEGIN后直接退出




====================
awk 编程模型
====================
理解awk为程序员提供的基本模型是很重要的 .  为什么awk对其他编程语言来说更易学 , awk 提供一些已经定义好的并且有用的模型是原因之一
awk 程序由被我们称为 main input loop 组成
一次循环就处理一次 , 直到出现某种情况结束.  你不需要自己来写这个循环
它已经在你写的代码的框架之中了.main input look 在awk中是每从输入中读去一行就进行一次新的处理   在别的语言中,你还 要自己创建这么个main input loop 来打开文件 并一次读一行, 这对于处理很多工作是没有必要的, 而awk让你编程更容易

当有多行输入时awk就执行多次, 就象hello world例子中, 只有从输入读取到一行时, 它才执行 , 当没有输入可读就结束

awk 允许两种方法 在读到输入前和读取输入后执行你的动作
也就是说 你可以在main input loop之前和 main input loop结束后执行一些处理动作,使用BEGIN和END过程

你可以认为awk脚本隐含3个主要部分: 读取输入前干什么 读取时干什么 读取后干什么下面这图说明awk怎么控制3部分的关系



awk一般的工作都是在main input loop中 也就是真正关心的是读取的行
这个过程你的awk动作将对每一行应用

====================
模式的匹配  
====================
其实就是 用RE匹配读入的行
hello word 脚本没有演示awk在模式匹配中的强大
当awk读一行就测试这行是否模式匹配脚本中的规则 只有符合模式匹配的行才作为动作的处理对象   如果没有指定动作 , 匹配的行将进行打印
考虑下面的指令
  1. /^$/ { print "This is a blank line." }
复制代码

如果读取的输入是空那么打印 这里模式的匹配是一个RE指定空行
我们把上面的指令放到一个名为 awkscr 的脚本中 , test文件作为输入, test内容是3个空行  然后使用下面的命令来执行脚本
  1. $ awk -f awkscr test
  2. This is a blank line.
  3. This is a blank line.
  4. This is a blank line.
复制代码


脚本告诉我们test 中有3空行, 忽略非空的行
我们再来加点规则到脚本中  现在这个脚本用来分析输入 并分类读入的每行是数字 字符还是空行
  1. # test for integer, string or empty line.
  2. /[0-9]+/    { print "That is an integer" }
  3. /[A-Za-z]+/ { print "This is a string" }
  4. /^$/        { print "This is a blank line." }
复制代码

下面是运行这个就脚本  从标准输入来读取
  1. $ awk -f awkscr
  2. 4
  3. That is an integer
  4. t
  5. This is a string
  6. 4T
  7. That is an integer
  8. This is a string
  9. RETURN
  10. This is a blank line.
  11. 44
  12. That is an integer
  13. CTRL-D
  14. $
复制代码

注意 当输入为4T时被表示既是文本也是字符.   一行可以匹配多个规则 ,  你可以写严格一点的规则来防止一行匹配多个规则   你也可以写动作来跳过脚本中的一部分

====================
描述你的脚本
====================
adding comments as you write the scripts is a good practice. A comment begins with the "#" character and ends at a newline.
与sed 不同的是awk允许你在脚本的任何地方注释
  1. As we begin writing scripts, we'll use comments do describe the action:
  2. #  blank.awk -- Print message for each blank line.
  3. /^$/ { print "This is a blank line." }
复制代码
0 0
原创粉丝点击