我们知道我们可以使用这两种技术从文件中获取我们想要的行的第二列:
awk '/WORD/ { print $2 }' filename
或者
grep WORD filename| cut -f 2 -d ' '
我的问题是:
- 上面两个命令有什么区别?
- 哪一款的性能最好?
awk
using相对于 using有何优点cut
,反之亦然?awk
给我们什么选择cut
,反之亦然?
答案1
两条线之间最显着的区别取决于输入。cut
采用单个字符-d
作为字段分隔符(默认为 TAB),并且该字符的每次出现都会启动一个新字段。awk
然而,更加灵活。分隔符位于FS
变量中,可以是空字符串(每个输入字符构成一个单独的字段)、单个字符或正则表达式。单个空格字符(默认)的特殊情况意味着在任何顺序的空白。另外,awk
默认情况下会抑制前导空格。
请比较:
$ echo "abc def" | cut -f 2 -d ' '
def
$ echo "abc def" | cut -f 2 -d ' '
$ echo " abc def" | cut -f 2 -d ' '
abc
$ echo "abc def" | awk '{ print $2 }'
def
$ echo "abc def" | awk '{ print $2 }'
def
$ echo " abc def" | awk '{ print $2 }'
def
在这里,根据和awk
之间的空格序列进行分割,而将每个空格作为分隔符。abc
def
cut
你采取什么取决于你想要实现什么。否则,我希望cut
速度更快,因为它是一个较小的、单一用途的工具,但awk
有自己的编程语言。
答案2
一般来说,工具越专业,速度就越快。因此,在大多数情况下,您可以期望cut
和grep
比 更快sed
,并且sed
比 更快awk
。如果您要将更简单工具的较长管道与更复杂工具的单次调用进行比较,则没有经验法则。这仅对大量输入(例如,数百万行)有意义;对于简短的输入,您不会看到任何差异。
更复杂的工具的优点当然是它们可以做更多的事情。
您的命令不必要地使用 cat 。请改用重定向(特别是如果您担心速度,尽管在运行基准测试之前您可能不应该担心速度)。
<fileName awk '/WORD/ { print $2 }'
<fileName grep WORD | cut -f 2 -d ' '
这些命令几乎是等效的。差异是:
- awk 和 grep 有不同的正则表达式语法。 awk 和
grep -E
具有几乎相同的 regexp 语法(扩展正则表达式)。 cut -d ' '
将每个单独的空格字符视为分隔符。 awk 的默认分隔符是任意空白序列,可以是多个空格、制表符等。您不能使用任意空白序列作为 的分隔符cut
。要在 awk 中使用单个空格作为分隔符,请将字段分隔符设置为匹配单个空格的正则表达式,而不是由单个空格组成的正则表达式(这是一种特殊情况,表示“任何空白序列”,即默认值):awk -F '[ ]' '/WORD/ {print $2}'
。
^ 程序优化的第一条规则:不要这样做。程序优化的第二条规则(仅限专家!):先不要这样做。—迈克尔·杰克逊
答案3
您的命令,
cat fileName | awk '/WORD/ { print $2 }'
你甚至不需要cat
命令。你可以尝试,
awk '/WORD/ { print $2 }' filename
下面的命令将输出从 cat 重定向到 grep,然后再进行 cut,
cat fileName | grep WORD | cut -f 2 -d ' '
最有可能的是我们必须避免输出重定向。 awk 在一行中完成这项工作,但cut
需要一个grep
命令来仅获取包含特定单词的行,并根据分隔符空格打印第 2 列。
如果 cut 失败,你可以在 awk 中执行这些操作。