【问题标题】:Optimizing grep -f piping commands [duplicate]优化 grep -f 管道命令 [重复]
【发布时间】:2018-12-17 21:47:45
【问题描述】:

我有两个文件。

file1 有一些以 abc 开头的键在第二列

et1 abc
et2 abc
et55 abc  

file2 具有第 1 列的值和一些我需要加起来的其他数字:

1 2 3 4 5 et1
5 5 5 5 5 et100
3 3 3 3 3 et55
5 5 5 5 4 et1
6 6 6 6 3 et1

对于文件1中提取的键,如果匹配,我需要将对应的第5列相加。 File2本身很大

这个命令似乎可以工作,但速度很慢:

 egrep -isr "abc" file1.tcl | awk '{print $1}' | grep -vwf /dev/stdin file2.tcl | awk '{tl+=$5} END {print tl}'

我将如何优化管道。还有我用 grep -f 做错了什么。是不是一般不建议做这样的事情。

编辑:当 file1 中存在 column6 键时,预期输出是 file2 中所有 column5 的总和

Edit2:预期输出:由于文件 1 具有键“et1、et2 和 et55”,因此在文件 2 中将第 5 列与第 1、3、4 和 5 行中的匹配键相加,预期输出为 [5+3+ 4+3=15]

【问题讨论】:

  • 请将该示例输入的所需输出添加到您的问题中。
  • 管道 grep 到 awk 几乎总是多余的,因为 awk 具有内置的正则表达式匹配。
  • -r 选项在您 grepping 特定文件时不是必需的,没有可递归到的目录。
  • 当 file1 中存在 column6 键时,预期输出是 file2 中所有 column5 的总和
  • 不要只是告诉我们,要展示给我们看。 edit您的问题以显示预期的输出。

标签: bash awk grep


【解决方案1】:

使用单个awk 将file1 读入数组的键中。然后在读取file2时,当$6在数组中时,将$5添加到总变量中。

awk 'NR==FNR {if ($2 == "abc") a[$1] = 0; 
              next}
     $6 in a {total += $5}
     END { print total }
    ' file1.tcl file2.tcl

【讨论】:

  • @EdMorton 不需要,因为我将它们全部初始化为 0。
  • 但事实证明他不想要每个键的总数,只想要一个总计。
  • 谢谢。可能是最后一个问题:我将如何优化原始帖子中的 grep/awk 管道,同时对管道进行最小的更改。 grep -f 天生就慢吗?
  • 不,不特别。但是两个进程通常比一个进程慢,除非grep 明显快于awk 的内置匹配。而grep要搜索整行,awk只能匹配特定字段。
【解决方案2】:

您能否尝试以下操作,首先读取 Input_file2.tcl 并减少循环。由于您的预期输出尚不清楚,因此尚未完全测试它。

awk 'FNR==NR{a[$NF]+=$(NF-1);next} $2=="abc"{print $1,a[$1]+0}'  file2.tcl file1.tcl

【讨论】:

  • a[$1]?a[$1]:0 -> a[$1]+0
  • 虽然做了一些不必要的工作,但这可能比反之更快。
  • @karakfa,现在肯定改了,谢谢你告诉我。
猜你喜欢
  • 1970-01-01
  • 2017-01-12
  • 2013-05-18
  • 2018-12-11
  • 2020-06-10
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
相关资源
最近更新 更多