James Pearson 发布的文章

文本处理是Unix的核心。从管道到/proc子系统,“一切都是文件”的理念贯穿于操作系统和所有基于它构造的工具。正因为如此,轻松地处理文本是一个期望成为Linux系统管理员甚至是资深用户的最重要的技能之一,而 awk是通用编程语言之外最强大的文本处理工具之一。

最简单的awk的任务是从标准输入中选择字段;如果你对awk除了这个用途之外,从来没了解过它的其他用途,你会发现它还是会是你身边一个非常有用的工具。

默认情况下,awk通过空格分隔输入。如果您想选择输入的第一个字段,你只需要告诉awk输出$ 1:

$ echo 'one two three four' | awk '{print $1}'
one

(是的,大括号语法是有点古怪,但我保证这是我们这节课一直会遇到。)

你能猜出如何选择第二,第三或第四个字段么?是的,分别用$2,$ 3,$ 4。

$ echo 'one two three four' | awk '{print $3}'
three

通常在文本改写时,你需要创建一个特定的数据格式,并且它覆盖不止一个单词。好消息是,awk中可以很容易地打印多个字段,甚至包含静态字符串:

 $ echo 'one two three four' | awk '{print $3,$1}' 
three one

$ echo 'one two three four' | awk '{print "foo:",$3,"| bar:",$1}' 
foo: three | bar: one

好吧,如果你的输入不是由空格分隔怎么办?只需用awk中的'-F'标志指定你的分隔符:

$ echo 'one mississippi,two mississippi,three mississippi,four mississippi' | awk -F , '{print $4}' 
four mississippi

偶尔间,你会发现自己正在处理字段数量不同的数据,但你只知道你想要的最后字段。 awk中内置的$NF变量代表字段的数量,这样你就可以用它来抓取最后一个元素:

$ echo 'one two three four' | awk '{print $NF}' 
four

你也可以用$NF做简单的数学,假如你需要倒数第二个字段:

$ echo 'one two three four' | awk '{print $(NF-1)}' 
three

甚至是中间的字段:

$ echo 'one two three four' | awk '{print $((NF/2)+1)}' 
three

而且这一切都非常有用,同样你可以摆脱强制使用sed,cut,和grep来得到这些结果(尽管要做更多的操作)。

因此,我将最后为你介绍awk的一个特性,维持跨行状态。

 $ echo -e 'one 1\ntwo 2' | awk '{print $2}' 

1

2

$ echo -e 'one 1\ntwo 2' | awk '{sum+=$2} END {print sum}' 
3

(END代表的是我们在执行完每行的处理之后只处理下面的代码块)

这里我使用的例子是统计web服务器请求日志的字节大小。想象一下我们有如下这样的日志:

$ cat requests.log 

Jul 23 18:57:12 httpd[31950]: "GET /foo/bar HTTP/1.1" 200 344

Jul 23 18:57:13 httpd[31950]: "GET / HTTP/1.1" 200 9300

Jul 23 19:01:27 httpd[31950]: "GET / HTTP/1.1" 200 9300

Jul 23 19:01:55 httpd[31950]: "GET /foo/baz HTTP/1.1" 200 6401

Jul 23 19:02:31 httpd[31950]: "GET /foo/baz?page=2 HTTP/1.1" 200 6312

我们知道最后一个字段是响应的字节大小。我们已经学习了如何使用$NF来抽取他们:

$ < requests.log awk '{print $NF}' 

344

9300

9300

6401

6312

接着我们可以将它们累加到一个变量中来收集我们的web服务其在日志中这段时间内的响应客户端的字节数量

$ < requests.log awk '{totalBytes+=$NF} END {print totalBytes}' 
31657

如果你正在寻找关于awk的更多资料,你可以在Amazon中花费不到15美元买到原始awk手册的二手书。你也许还可以看看Eric Pement的单行awk命令收集这本书。


via: http://xmodulo.com/2014/07/use-awk-command-linux.html

作者:James Pearson 译者:geekpi 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

有时,关系型相关数据库系统的复杂性会把你搞晕,不过幸运的是,使用MySQL工具来管理查询就就可以避免这些复杂性。 在本教程中,我将向你们展示 怎样去查找并杀掉任何非法的MySQL查询

为了浏览当前正在运行的查询,登陆到MySQL终端,然后运行‘show processlist’命令:

mysql> show processlist; 

+--------+--------+-----------------+---------+---------+-------+-------+------------------+-----------+---------------+-----------+
| Id     | User   | Host            | db      | Command | Time  | State | Info             | Rows_sent | Rows_examined | Rows_read |
+--------+--------+-----------------+---------+---------+-------+-------+------------------+-----------+---------------+-----------+
|  78233 | root   | 127.0.0.1:37527 | mysql   | Sleep   | 16474 |       | NULL             |         6 |             6 |         6 |
|  84546 | root   | 127.0.0.1:48593 | mysql   | Sleep   | 13237 |       | NULL             |         2 |             2 |         2 |
| 107083 | root   | 127.0.0.1:56451 | mysql   | Sleep   | 15488 |       | NULL             |         1 |           121 |       121 |
| 131455 | root   | 127.0.0.1:48550 | NULL    | Query   |     0 | NULL  | show processlist |         0 |             0 |         0 |
+--------+--------+-----------------+---------+---------+-------+-------+------------------+-----------+---------------+-----------+
4 rows in set (0.03 sec)

首先你应该查看'Time'项,这里记录了进程执行 "做其当做的事情" 操作的秒数。‘command’项处于‘Sleep’ 状态的进程表示其正在等待接受查询,因此,它并没有消耗任何资源。对于其他任何进程而言,‘Time’超过一定的秒数表明出现问题。

在上面的例子中,唯一运行的查询是我们的‘show processlist’命令。让我们来看看如果我们有一个写的很烂的查询是怎么样的:

mysql> show processlist; 

+--------+--------+-----------------+-----------+---------+-------+--------------+----------------------------------+-----------+---------------+-----------+
| Id     | User   | Host            | db        | Command | Time  | State        | Info                             | Rows_sent | Rows_examined | Rows_read |
+--------+--------+-----------------+-----------+---------+-------+--------------+----------------------------------+-----------+---------------+-----------+
|  78233 | root   | 127.0.0.1:37527 | example   | Sleep   | 18046 |              | NULL                             |         6 |             6 |         6 |
|  84546 | root   | 127.0.0.1:48593 | example   | Sleep   | 14809 |              | NULL                             |         2 |             2 |         2 |
| 107083 | root   | 127.0.0.1:56451 | example   | Sleep   | 17060 |              | NULL                             |         1 |           121 |       121 |
| 132033 | root   | 127.0.0.1:54642 | example   | Query   |    27 | Sending data | select max(subtotal) from orders |         0 |             0 |         0 |
| 133933 | root   | 127.0.0.1:48679 | NULL      | Query   |     0 | NULL         | show processlist                 |         0 |             0 |         0 |
| 134122 | root   | 127.0.0.1:49264 | example   | Sleep   |     0 |              | NULL                             |         0 |             0 |         0 |
+--------+--------+-----------------+-----------+---------+-------+--------------+----------------------------------+-----------+---------------+-----------+
6 rows in set (0.00 sec)

啊哈!现在我们看到有一个查询运行了将近30秒。如果我们不想让它的进程继续运行,可以将它的'Id'传递给kill命令:

mysql> kill 132033;
Query OK, 0 rows affected (0.00 sec)
mysql> 

(注意 由于我们没有改变任何数据,MySQL总是报告0行被影响。)

明智的使用kill命令能够清除积压的查询。然而,要记住的是,那不是一种永久的方法 - 如果这些查询来自你的程序,你需要去重写它们,或者将继续看到相同的问题不断出现。

另请参阅

关于不同‘命令’的MySQL文档:


via: http://xmodulo.com/2014/07/find-kill-misbehaving-mysql-queries.html

译者:hunanchenxingyu 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出