首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >边打边圈+慢慢来

边打边圈+慢慢来
EN

Stack Overflow用户
提问于 2015-02-24 13:04:58
回答 3查看 1.4K关注 0票数 1

我正在尝试用bash循环处理一个文件(1.5GB)来迭代每一行。为了简单(相对的),我使用了cut,最后得到了:

代码语言:javascript
复制
while read line
do
    echo "$(echo $line | cut -d' ' -f 2-3)" "$(echo $line | cut -d'"' -f 20)"
done < TEST.log > IDS.log

这是非常慢的,只做大约2kb/秒。我需要一些能跑得更快的东西。

此外,这里的瓶颈是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-24 13:09:13

瓶颈可能是您为每一行数据生成了几个进程。至于替换,这个awk应该是等价的:

代码语言:javascript
复制
awk '{ split($0, a, "\""); print $2, $3, a[20] }' TEST.log > IDS.log
票数 4
EN

Stack Overflow用户

发布于 2015-02-24 13:49:04

Perl通常非常快:

代码语言:javascript
复制
perl -nE 'say join " ", (split " ")[1,2], (split /"/)[19]' TEST.log > IDS.log

Perl数组从0开始进行索引。

票数 4
EN

Stack Overflow用户

发布于 2019-02-14 18:13:01

这里最大的瓶颈是剥离管道的子进程。只要去掉命令替换和管道,您就可以获得相当大的性能改进(读起来:数量级)。

代码语言:javascript
复制
while IFS=$'\x01' read -r ss1 ss2 ss3 _ <&3 && \
      IFS='"' read -r -a quote_separated_fields; do
    printf '%s\n' "${ss2} ${ss3} ${quote_separated_fields[20]}"
done < TEST.log 3< <(tr ' ' $'\x01' <TEST.log) > IDS.log

这是怎么回事?

  • tr ' ' $'\x01'将输入中的空格更改为低ASCII字符,以避免特殊情况处理(其中read将将运行的空白合并为单个字符)。将其放在3< <(...)之后,将此操作的输出放在文件描述符#3上。
  • IFS=$'\x01' read -r ss1 ss2 ss3 _ <&3在这些字符上拆分一行,将第一个字段放入ss1 (我们并不关心),将第二个字段放入ss2,将第三个字段放入ss3,将行的其余部分放入_<&3使这一行从文件描述符3中读取。
  • IFS='"' read -r -a quote_separated_fields"字符上的stdin (FD 0)输入拆分为一个名为quote_separated_fields的数组。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28696604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档