mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-02-03 23:40:14 +08:00
Translated 20191125 How to use loops in awk.md
This commit is contained in:
parent
81b86eb79f
commit
b2b373daec
@ -1,162 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lxbwolf)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to use loops in awk)
|
||||
[#]: via: (https://opensource.com/article/19/11/loops-awk)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
How to use loops in awk
|
||||
======
|
||||
Learn how to use different types of loops to run commands on a record
|
||||
multiple times.
|
||||
![arrows cycle symbol for failing faster][1]
|
||||
|
||||
Awk scripts have three main sections: the optional BEGIN and END functions and the functions you write that are executed on each record. In a way, the main body of an awk script is a loop, because the commands in the functions run for each record. However, sometimes you want to run commands on a record more than once, and for that to happen, you must write a loop.
|
||||
|
||||
There are several kinds of loops, each serving a unique purpose.
|
||||
|
||||
### While loop
|
||||
|
||||
A **while** loop tests a condition and performs commands _while_ the test returns _true_. Once a test returns _false_, the loop is broken.
|
||||
|
||||
|
||||
```
|
||||
#!/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
# Print the squares from 1 to 10
|
||||
|
||||
i=1;
|
||||
while (i <= 10) {
|
||||
print "The square of ", i, " is ", i*i;
|
||||
i = i+1;
|
||||
}
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
In this simple example, awk prints the square of whatever integer is contained in the variable _i_. The **while (i <= 10)** phrase tells awk to perform the loop only as long as the value of _i_ is less than or equal to 10. After the final iteration (while _i_ is 10), the loop ends.
|
||||
|
||||
### Do while loop
|
||||
|
||||
The **do while** loop performs commands after the keyword **do**. It performs a test afterward to determine whether the stop condition has been met. The commands are repeated only _while_ the test returns true (that is, the end condition has _not_ been met). If a test fails, the loop is broken because the end condition has been met.
|
||||
|
||||
|
||||
```
|
||||
#!/usr/bin/awk -f
|
||||
BEGIN {
|
||||
|
||||
i=2;
|
||||
do {
|
||||
print "The square of ", i, " is ", i*i;
|
||||
i = i + 1
|
||||
}
|
||||
while (i < 10)
|
||||
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
### For loops
|
||||
|
||||
There are two kinds of **for** loops in awk.
|
||||
|
||||
One kind of **for** loop initializes a variable, performs a test, and increments the variable together, performing commands while the test is true.
|
||||
|
||||
|
||||
```
|
||||
#!/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
for (i=1; i <= 10; i++) {
|
||||
print "The square of ", i, " is ", i*i;
|
||||
}
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
Another kind of **for** loop sets a variable to successive indices of an array, performing a collection of commands for each index. In other words, it uses an array to "collect" data from a record.
|
||||
|
||||
This example implements a simplified version of the Unix command **uniq**. By adding a list of strings into an array called **a** as a key and incrementing the value each time the same key occurs, you get a count of the number of times a string appears (like the **\--count** option of **uniq**). If you print the keys of the array, you get every string that appears one or more times.
|
||||
|
||||
For example, using the demo file **colours.txt** (from the previous articles):
|
||||
|
||||
|
||||
```
|
||||
name color amount
|
||||
apple red 4
|
||||
banana yellow 6
|
||||
raspberry red 99
|
||||
strawberry red 3
|
||||
grape purple 10
|
||||
apple green 8
|
||||
plum purple 2
|
||||
kiwi brown 4
|
||||
potato brown 9
|
||||
pineapple yellow 5
|
||||
```
|
||||
|
||||
Here is a simple version of **uniq -c** in awk form:
|
||||
|
||||
|
||||
```
|
||||
#! /usr/bin/awk -f
|
||||
|
||||
NR != 1 {
|
||||
a[$2]++
|
||||
}
|
||||
END {
|
||||
for (key in a) {
|
||||
print a[key] " " key
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The third column of the sample data file contains the number of items listed in the first column. You can use an array and a **for** loop to tally the items in the third column by color:
|
||||
|
||||
|
||||
```
|
||||
#! /usr/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
FS=" ";
|
||||
OFS="\t";
|
||||
print("color\tsum");
|
||||
}
|
||||
NR != 1 {
|
||||
a[$2]+=$3;
|
||||
}
|
||||
END {
|
||||
for (b in a) {
|
||||
print b, a[b]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, you are also printing a header column in the BEFORE function (which always happens only once) prior to processing the file.
|
||||
|
||||
### Loops
|
||||
|
||||
Loops are a vital part of any programming language, and awk is no exception. Using loops can help you control how your awk script runs, what information it's able to gather, and how it processes your data. Our next article will cover switch statements, **continue**, and **next**.
|
||||
|
||||
* * *
|
||||
|
||||
Would you rather listen to this article? It was adapted from an episode of [Hacker Public Radio][2], a community technology podcast by hackers, for hackers.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/loops-awk
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/fail_progress_cycle_momentum_arrow.png?itok=q-ZFa_Eh (arrows cycle symbol for failing faster)
|
||||
[2]: http://hackerpublicradio.org/eps.php?id=2330
|
163
translated/tech/20191125 How to use loops in awk.md
Normal file
163
translated/tech/20191125 How to use loops in awk.md
Normal file
@ -0,0 +1,163 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "lxbwolf"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
[#]: subject: "How to use loops in awk"
|
||||
[#]: via: "https://opensource.com/article/19/11/loops-awk"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
|
||||
在 awk 中怎么使用循环
|
||||
======
|
||||
来学习一下多次执行同一条命令的不同类型的循环。
|
||||
![arrows cycle symbol for failing faster][1]
|
||||
|
||||
awk 脚本有三个主要部分:BEGIN 和 END 函数(都可选),用户自己写的每次要执行的函数。某种程度上,awk 的主体部分就是一个循环,因为函数中的命令对每一条记录都会执行一次。然而,有时你希望对于一条记录执行多次命令,那么你就需要用到循环。
|
||||
|
||||
有多种类型的循环,分别适合不同的场景。
|
||||
|
||||
### while 循环
|
||||
|
||||
一个 while 循环检测一个表达式,如果表达式为 *true* 就执行命令。当表达式变为 *false* 时,循环中断。
|
||||
|
||||
|
||||
```
|
||||
#!/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
# Print the squares from 1 to 10
|
||||
|
||||
i=1;
|
||||
while (i <= 10) {
|
||||
print "The square of ", i, " is ", i*i;
|
||||
i = i+1;
|
||||
}
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
在这个简单实例中, awk 打印了变量 *i* 中的整数值的平方。**while (i <= 10)** 语句告诉 awk 仅在 *i* 的值小于或等于 10 时才执行循环。在循环最后一次执行时(*i* 的值是 10),循环终止。
|
||||
|
||||
### Do while 循环
|
||||
|
||||
do-while 循环在关键字 **do** 之后执行命令。在每次循环结束时检测一个表达式来决定是否终止循环。仅在表达式返回 true 时才会重复执行命令(即还没有到终止循环的条件)。如果表达式返回 false,因为到了终止循环的条件所以循环被终止。
|
||||
|
||||
|
||||
```
|
||||
#!/usr/bin/awk -f
|
||||
BEGIN {
|
||||
|
||||
i=2;
|
||||
do {
|
||||
print "The square of ", i, " is ", i*i;
|
||||
i = i + 1
|
||||
}
|
||||
while (i < 10)
|
||||
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
### for 循环
|
||||
|
||||
awk 中有两种 **for**循环。
|
||||
|
||||
一种 **for** 循环初始化一个变量,检测一个表达式,执行变量递增,当表达式的结果为 true 时循环就会一直执行。
|
||||
|
||||
|
||||
```
|
||||
#!/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
for (i=1; i <= 10; i++) {
|
||||
print "The square of ", i, " is ", i*i;
|
||||
}
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
另一种 **for** 循环设置一个有连续 index 的数组变量,对每一个索引执行一个命令集。换句话说,它用一个数组「收集」每一条命令执行后的结果。
|
||||
|
||||
本例实现了一个简易版的 Unix 命令 **uniq** 。通过把一系列字符串作为 key 加到数组 a 中,当相同的 key 再次出现时就增加 value 的值,可以得到某个字符串出现的次数(就像 **uniq** 的 **--count** 选项)。如果你打印该数组的所有 key,将会得到出现过的所有字符串。
|
||||
|
||||
用 demo 文件 **colours.txt** (前一篇文章中的文件)来举例:
|
||||
|
||||
|
||||
```
|
||||
name color amount
|
||||
apple red 4
|
||||
banana yellow 6
|
||||
raspberry red 99
|
||||
strawberry red 3
|
||||
grape purple 10
|
||||
apple green 8
|
||||
plum purple 2
|
||||
kiwi brown 4
|
||||
potato brown 9
|
||||
pineapple yellow 5
|
||||
```
|
||||
|
||||
|
||||
|
||||
这是 awk 版的简易 **uniq -c**:
|
||||
|
||||
|
||||
```
|
||||
#! /usr/bin/awk -f
|
||||
|
||||
NR != 1 {
|
||||
a[$2]++
|
||||
}
|
||||
END {
|
||||
for (key in a) {
|
||||
print a[key] " " key
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
示例数据文件的第三列是第一列列出的条目的计数。你可以用一个数组和 **for** 循环来从 color 维度统计第三列的条目。
|
||||
|
||||
|
||||
```
|
||||
#! /usr/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
FS=" ";
|
||||
OFS="\t";
|
||||
print("color\tsum");
|
||||
}
|
||||
NR != 1 {
|
||||
a[$2]+=$3;
|
||||
}
|
||||
END {
|
||||
for (b in a) {
|
||||
print b, a[b]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
你可以看到,在处理文件之前也需要在 **前置** 函数(仅仅执行一次)中打印一列表头。
|
||||
|
||||
### 循环
|
||||
|
||||
在任何编程语言中循环都是很重要的一部分,awk 也不例外。使用循环你可以控制 awk 脚本怎样去运行,它可以统计什么信息,还有它怎么去处理你的数据。我们下一篇文章会讨论 switch 语句,**continue** 和 **next**。
|
||||
|
||||
* * *
|
||||
|
||||
你是否更想听这篇文章?本文已被收录进 [Hacker Public Radio](http://hackerpublicradio.org/eps.php?id=2330),一个来自黑客,面向黑客的社区技术博客。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/loops-awk
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/fail_progress_cycle_momentum_arrow.png?itok=q-ZFa_Eh "arrows cycle symbol for failing faster"
|
||||
[2]: http://hackerpublicradio.org/eps.php?id=2330
|
Loading…
Reference in New Issue
Block a user