【问题标题】:Filter lines by number of fields按字段数过滤行
【发布时间】:2014-08-30 09:47:15
【问题描述】:

我在 Linux 中过滤非常长的文本文件(通常 > 1GB)以仅获取我感兴趣的那些行。我使用以下命令:

cat ./my/file.txt | LC_ALL=C fgrep -f ./my/patterns.txt | $decoder > ./path/to/result.txt

$decoder 是我用于解码这些文件的程序的路径。现在的问题是它只接受带有 7 个字段 的行,即 7 个​​由空格分隔的字符串(例如“11 22 33 44 55 66 77”)。每当将具有更多或更少字段的字符串传递给该程序时,它都会崩溃,并且我会收到一条损坏的管道错误消息。

为了解决这个问题,我在Bash写了一个超级简单的脚本:

while read line ; do
    if [[ $( echo $line | awk '{ print NF }') == 7 ]]; then
        echo $line;
    fi;
done

但问题是现在需要很长时间才能完成。以前需要几秒钟,现在需要大约 30 分钟。

有人知道更好/更快的方法吗?提前谢谢你。

【问题讨论】:

  • 试试:LC_ALL=C fgrep -f ./my/patterns.txt ./my/file.txt | $decoder > ./path/to/result.txt

标签: linux bash awk grep pipe


【解决方案1】:

也许您可以在两者之间插入awk。无需依赖 Bash:

LC_ALL=C fgrep -f ./my/patterns.txt ./my/file.txt | awk 'NF == 7' | "$decoder" > ./path/to/result.txt

也许awk 可以成为首发。这样性能可能会更好:

awk 'NF == 7' ./my/file.txt | LC_ALL=C fgrep -f ./my/patterns.txt | "$decoder" > ./path/to/result.txt

您可以将 fgrepawk 合并为单个 awk 命令,但我不确定这是否会影响需要 LC_ALL=C 的任何内容,并且它会提供更好的性能。

【讨论】:

  • 谢谢,太棒了,现在比以前更快了!
猜你喜欢
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 2019-04-15
  • 2021-10-23
  • 2016-04-03
  • 1970-01-01
相关资源
最近更新 更多