Awk vs Awk + ​​cut vs. bash

时间:2013-12-08 10:12:24

标签: linux bash awk grep cut

我们都知道总有多种方法可以解决问题。我想知道在一个案例中每个特定解决方案的优点和缺点是什么。时间和空间(也许是清洁 - 但这是主观的,所以不是主要关注点)。

你有一个文件,它也包含包含字符串xyz的行,但不是唯一的。您感兴趣的是在特定列中整数值应满足条件的行。

我使用它的一个例子是从sslscan输出中过滤弱密码。这不是特定的时间,也不是空间密集的,所以这个例子只是为了更清楚地了解它的外观。

问题出现了,当我试图寻找解决方案时,我在stackoverflow上找到了各种不同的答案,然后我自己想出了一些东西。

可能的解决方案1(纯awk):

awk '$0~/xyz/ && $3 < 128 {$1=""; print}' file-with-data.txt

可能的解决方案2(awk + ​​cut):

awk '$0~/xyz/ && $3 < 128' file-with-data.txt | cut -c15-

可能的解决方案3(bash):

grep xyz file-with-data.txt | while read -r line
do if [ $(echo $line | cut -d" " -f3)  -le 127 ]
   then echo $line
   fi
done

1 个答案:

答案 0 :(得分:7)

shell是一个可以从中调用工具的环境。它具有某些编程语言结构,可帮助您对调用工具的顺序进行排序。它没有被创建,也没有以任何方式(例如语言结构)进行优化,解析文本文件。

创建了Awk来解析文本文件。它的执行范例是基于它(输入记录的内置循环),它有特定的结构来帮助它(例如BEGIN和END部分,变量NR,FNR,NF等)。

任何时候你在shell中编写一个循环来解析一个文本文件你都有错误的方法,你编写的shell循环与awk脚本不同,在给定各种输入值的情况下会隐式失败,你运行它的目录的内容,你所使用的操作系统等......

IF you just need to find a string or RE in some text
THEN
    use grep
ELIF you just need to select a single-char-separated field
THEN
    use cut
ELIF you just need to do a simple subsitution for an RE on a single line
THEN
    use sed
ELSE
    use awk
ENDIF

这些方法中有哪些可供选择:

awk '$0~/xyz/ && $3 < 128 {$1=""; print}' file-with-data.txt
awk '$0~/xyz/ && $3 < 128' file-with-data.txt | cut -c15-

没关系。第二个有一点开销,但你永远不会注意到它所以只选择最符合你要求的那个(例如,真的想用空白替换第一个字段,还是你真的想要削减N个字符?)你并且最容易让你写作和理解。就个人而言,如果需要剪切,我只会留在awk并使用substr()。